实用优先基础
从一组受限的基本工具中构建复杂组件。
概要
传统上,每当您需要在网页上设置样式时,您会编写 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-lg flex items-center space-x-4">
<div class="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-slate-500">You have a new message!</p>
</div>
</div>在上面的例子中,我们使用了:
- Tailwind 的 flexbox 和 padding 工具(
flex、shrink-0和p-6)来控制整体卡片布局 - max-width 和 margin 工具(
max-w-sm和mx-auto)用于限制卡片的宽度并使其水平居中 - 背景颜色、边框半径和阴影效果工具(
bg-white、rounded-xl和shadow-lg)用于设置卡片的外观 - 利用宽度和高度工具(
w-12和h-12)调整标志图像的大小 - 空间间隔实用程序(
space-x-4)用于处理标志和文本之间的间距 - 字体大小、文本颜色和字重工具(
text-xl、text-black、font-medium等)用于设置卡片文本的样式。
这种方法使我们能够实现完全定制的组件设计,而无需编写一行自定义的 CSS。
现在我知道你在想什么,“这太可怕了,多么糟糕的混乱!” 你说得对,它有点丑。事实上,第一次看到它几乎不可能认为这是一个好主意 — 你必须实际尝试一下。
但一旦你真的用这种方式建立了一些东西,你会很快注意到一些非常重要的好处:
- 你不再浪费精力去创造类名。不再添加像
sidebar-inner-wrapper这样的愚蠢类名,只是为了能够对某些东西进行样式设置,也不再为那些实际上只是一个 flex 容器的东西苦苦思索一个完美的抽象名称。 - 你的 CSS 停止增长。使用传统方法,每次添加新功能时,您的 CSS 文件都会变得越来越大。使用实用工具,一切都是可重复使用的,因此您很少需要编写新的 CSS。
- 进行更改会更安全。CSS 是全局的,当你进行更改时,你永远不知道会影响到什么。HTML 中的类是局部的,因此你可以更改它们而不用担心其他地方会出现问题。
当你意识到只使用预定义的实用类在HTML中工作可以提高工作效率时,以其他方式工作会感觉像折磨。
为什么不直接使用内联样式?
对这种方法的常见反应是想知道,“这不就是内联样式吗?”在某种程度上确实是 — 你直接将样式应用于元素,而不是给它们分配一个类名,然后对该类进行样式设置。
但是使用实用类比内联样式有一些重要的优势:
- 在有限制条件下进行设计。使用内联样式,每个值都是一个魔术数字。通过使用实用程序,您可以从预定义的设计系统中选择样式,这样可以更轻松地构建视觉一致的用户界面。
- 响应式设计。您不能在内联样式中使用媒体查询,但您可以使用 Tailwind 的响应式工具轻松构建完全响应式的界面。
- 悬停、焦点和其他状态。内联样式无法针对悬停或焦点等状态,但Tailwind的状态变体使得使用实用类轻松地为这些状态设置样式。
该组件完全响应,并包括具有悬停和焦点样式的按钮,完全使用实用类构建:

Erin Lindford
Product Engineer
<div class="py-8 px-8 max-w-sm mx-auto bg-white rounded-xl shadow-lg 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: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-slate-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>除此之外,维护一个以实用为先的CSS项目比维护一个庞大的CSS代码库要容易得多,因为HTML比CSS容易维护得多。像GitHub、Netflix、Heroku、Kickstarter、Twitch、Segment等大公司都非常成功地采用了这种方法。
如果您想了解其他人使用这种方法的经验,请查看以下资源:
- 《数字之间:一年半的原子CSS》 by John Polacek
- 《不,实用类不同于内联样式》 by Sarah Dayan of Algolia
- Diana Mounter 在 GitHub 使用实用类,一个播客采访
要了解更多,请查看由 John Polacek 策划的《原子/实用优先CSS的案例》。