在一组受约束的原始功能类的基础上构建复杂的组件。
传统情况下,当您需要在网页上设置样式时,都需要编写 CSS。
使用传统方式时,定制的设计需要定制的 CSS
You have a new message!
<div class="chat-notification">
<div class="chat-notification-logo-wrapper">
<img class="chat-notification-logo" src="/img/logo.svg" alt="ChitChat Logo">
</div>
<div class="chat-notification-content">
<h4 class="chat-notification-title">ChitChat</h4>
<p class="chat-notification-message">You have a new message!</p>
</div>
</div>
<style>
.chat-notification {
display: flex;
max-width: 24rem;
margin: 0 auto;
padding: 1.5rem;
border-radius: 0.5rem;
background-color: #fff;
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.chat-notification-logo-wrapper {
flex-shrink: 0;
}
.chat-notification-logo {
height: 3rem;
width: 3rem;
}
.chat-notification-content {
margin-left: 1.5rem;
padding-top: 0.25rem;
}
.chat-notification-title {
color: #1a202c;
font-size: 1.25rem;
line-height: 1.25;
}
.chat-notification-message {
color: #718096;
font-size: 1rem;
line-height: 1.5;
}
</style>
使用 Tailwind,您可以通过直接在 HTML 中应用预先存在的类来设置元素的样式。
使用功能类构建自定义设计而无需编写 CSS
You have a new message!
<div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4">
<div class="flex-shrink-0">
<img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo">
</div>
<div>
<div class="text-xl font-medium text-black">ChitChat</div>
<p class="text-gray-500">You have a new message!</p>
</div>
</div>
在上面的示例中,我们使用了:
flex
, flex-shrink-0
, 和 p-6
) 来控制整体的卡片布局max-w-sm
和 mx-auto
) 来设置卡片的宽度和水平居中bg-white
, rounded-xl
, 和 shadow-md
) 设置卡片的外观样式w-12
and h-12
) 来设置 logo 图片的大小space-x-4
) 来处理 logo 和文本之间的间距text-xl
,text-black
,font-medium
等等) 给卡片文字设置样式这种方法使我们无需编写一行自定义的 CSS 即可实现一个完全定制的组件设计。
我知道您在想:"这太繁琐了,真是一团糟!" 您是对的,这有点丑陋。实际上,当您第一次看到它时,几乎不可能认为这是一个好主意--您必须实际尝试一下。
但是,一旦您以这种方式实际构建了一些东西,您就会很快注意到一些真正重要的优点:
sidebar-inner-wrapper
这样愚蠢的类名,不必再为了一个 flex 容器的完美抽象命名而倍受折磨。当您意识到在 HTML 中使用预定义的功能类是多么的富有成效时,以任何其他方式工作都感觉像是折磨。
对这种方式的一个普遍反应是, "这不就是内联样式吗?" 在某些方面是 — 您是将样式直接应用于元素,而不是为元素分配一个类,然后在这个类中设置样式。
但是使用功能类比内联样式具有一些重要的优点:
该组件完全响应,并包括具有 hover 和 focus 样式的按钮,完全由功能类构建:
Erin Lindford
Product Engineer
<div class="py-8 px-8 max-w-sm mx-auto bg-white rounded-xl shadow-md space-y-2 sm:py-4 sm:flex sm:items-center sm:space-y-0 sm:space-x-6">
<img class="block mx-auto h-24 rounded-full sm:mx-0 sm:flex-shrink-0" src="/img/erin-lindford.jpg" alt="Woman's Face">
<div class="text-center space-y-2 sm:text-left">
<div class="space-y-0.5">
<p class="text-lg text-black font-semibold">
Erin Lindford
</p>
<p class="text-gray-500 font-medium">
Product Engineer
</p>
</div>
<button class="px-4 py-1 text-sm text-purple-600 font-semibold rounded-full border border-purple-200 hover:text-white hover:bg-purple-600 hover:border-transparent focus:outline-none focus:ring-2 focus:ring-purple-600 focus:ring-offset-2">Message</button>
</div>
</div>
在使用功能优先的方式时,最大的可维护性问题是管理通用的可重复使用的功能类组合。
通过提取组件(通常做为模板片断或者组件),可以轻松解决此问题。
<!-- PrimaryButton.vue -->
<template>
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
<slot/>
</button>
</template>
您也可以使用 Tailwind 的 @apply
功能创建抽象的 CSS 类。
<!-- Using utilities -->
<button class="py-2 px-4 font-semibold rounded-lg shadow-md text-white bg-green-500 hover:bg-green-700">
Click me
</button>
<!-- Extracting classes using @apply -->
<button class="btn btn-green">
Button
</button>
<style>
.btn {
@apply py-2 px-4 font-semibold rounded-lg shadow-md;
}
.btn-green {
@apply text-white bg-green-500 hover:bg-green-700;
}
</style>
除此之外,维护功能优先的 CSS 项目比维护大型 CSS 代码库要容易得多,因为 HTML 比 CSS 维护容易得多。诸如 GitHub,Heroku,Kickstarter,Twitch,Segment 等大型公司都在使用这种方法,且取得巨大成功。
如果您想了解其他人使用此方法的经验,请查看以下资源:
查看 John Polacek 策划的 The Case for Atomic/Utility-First CSS 了解更多信息。