1. 核心概念
  2. 使用工具类进行样式设置

核心概念

使用工具类进行样式设置

从一组受限的原始工具构建复杂组件。

概述(Overview)

¥Overview

你可以通过在标记中直接组合许多单一用途的演示类(工具类)来使用 Tailwind 来设置样式:

¥You style things with Tailwind by combining many single-purpose presentational classes (utility classes) directly in your markup:

ChitChat

You have a new message!

<div class="mx-auto flex max-w-sm items-center gap-x-4 rounded-xl bg-white p-6 shadow-lg outline outline-black/5 dark:bg-slate-800 dark:shadow-none dark:-outline-offset-1 dark:outline-white/10"><img class="size-12 shrink-0" src="/img/logo.svg" alt="ChitChat Logo" /><div>  <div class="text-xl font-medium text-black dark:text-white">ChitChat</div>  <p class="text-gray-500 dark:text-gray-400">You have a new message!</p></div></div>

例如,在上面的 UI 中我们使用了:

¥For example, in the UI above we've used:

  • displaypadding 工具 (flexshrink-0p-6) 用于控制整体布局

    ¥The display and padding utilities (flex, shrink-0, and p-6) to control the overall layout

  • max-widthmargin 工具(max-w-smmx-auto)用于限制卡片宽度并将其水平居中

    ¥The max-width and margin utilities (max-w-sm and mx-auto) to constrain the card width and center it horizontally

  • background-colorborder-radiusbox-shadow 工具(bg-whiterounded-xlshadow-lg)用于设计卡片的外观

    ¥The background-color, border-radius, and box-shadow utilities (bg-white, rounded-xl, and shadow-lg) to style the card's appearance

  • widthheight 工具 (size-12) 用于设置徽标图片的宽度和高度

    ¥The width and height utilities (size-12) to set the width and height of the logo image

  • gap 工具 (gap-x-4) 用于处理徽标和文本之间的间距

    ¥The gap utilities (gap-x-4) to handle the spacing between the logo and the text

  • 用于设置卡片文本样式的 font-sizecolorfont-weight 工具(text-xltext-blackfont-medium 等)

    ¥The font-size, color, and font-weight utilities (text-xl, text-black, font-medium, etc.) to style the card text

以这种方式设置样式与许多传统的最佳实践相矛盾,但一旦你尝试,你就会很快注意到一些非常重要的好处:

¥Styling things this way contradicts a lot of traditional best practices, but once you try it you'll quickly notice some really important benefits:

  • 你可以更快地完成工作 - 你无需花时间想出类名、做出选择器决定或在 HTML 和 CSS 文件之间切换,因此你的设计可以非常快速地组合在一起。

    ¥You get things done faster — you don't spend any time coming up with class names, making decisions about selectors, or switching between HTML and CSS files, so your designs come together very fast.

  • 进行更改感觉更安全 — 向元素添加或删除工具类只会影响该元素,因此你永远不必担心意外破坏使用相同 CSS 的另一个页面。

    ¥Making changes feels safer — adding or removing a utility class to an element only ever affects that element, so you never have to worry about accidentally breaking something another page that's using the same CSS.

  • 维护旧项目更容易 — 更改某些内容仅意味着在项目中找到该元素并更改类,而不是试图记住你六个月未碰过的所有自定义 CSS 的工作方式。

    ¥Maintaining old projects is easier — changing something just means finding that element in your project and changing the classes, not trying to remember how all of that custom CSS works that you haven't touched in six months.

  • 你的代码更具可移植性 - 由于结构和样式都位于同一位置,你可以轻松地复制和粘贴整个 UI 块,即使在不同的项目之间也是如此。

    ¥Your code is more portable — since both the structure and styling live in the same place, you can easily copy and paste entire chunks of UI around, even between different projects.

  • 你的 CSS 停止增长 - 由于工具类是如此可重用,因此你的 CSS 不会随着你向项目添加的每个新功能而继续线性增长。

    ¥Your CSS stops growing — since utility classes are so reusable, your CSS doesn't continue to grow linearly with every new feature you add to a project.

这些好处对小型项目有很大影响,但对于大规模处理长期项目的团队来说,它们更有价值。

¥These benefits make a big difference on small projects, but they are even more valuable for teams working on long-running projects at scale.

为什么不直接使用内联样式?(Why not just use inline styles?)

¥Why not just use inline styles?

对这种方法的常见反应是想知道“这不就是内联样式吗?” 在某些方面确实如此 — 你将样式直接应用于元素,而不是为它们分配类名,然后为该类设置样式。

¥A common reaction to this approach is wondering, “isn’t this just inline styles?” and in some ways it is — you’re applying styles directly to elements instead of assigning them a class name and then styling that class.

但使用工具类比内联样式有许多重要优势,例如:

¥But using utility classes has many important advantages over inline styles, for example:

  • 使用约束进行设计 - 使用内联样式,每个值都是一个神奇的数字。使用工具,你可以从 预定义设计系统 中选择样式,这使得构建视觉一致的 UI 变得更加容易。

    ¥Designing with constraints — using inline styles, every value is a magic number. With utilities, you’re choosing styles from a predefined design system, which makes it much easier to build visually consistent UIs.

  • 悬停、聚焦和其他状态 — 内联样式无法针对悬停或聚焦等状态,但 Tailwind 的 状态变量 可以轻松地使用工具类来设置这些状态的样式。

    ¥Hover, focus, and other states — inline styles can’t target states like hover or focus, but Tailwind’s state variants make it easy to style those states with utility classes.

  • 媒体查询 — 你不能在内联样式中使用媒体查询,但你可以使用 Tailwind 的 响应式变体 轻松构建完全响应的界面。

    ¥Media queries — you can’t use media queries in inline styles, but you can use Tailwind’s responsive variants to build fully responsive interfaces easily.

此组件完全响应,包含具有悬停和活动样式的按钮,并且完全使用工具类构建:

¥This component is fully responsive and includes a button with hover and active styles, and is built entirely with utility classes:

Woman's Face

Erin Lindford

Product Engineer

<div class="flex flex-col gap-2 p-8 sm:flex-row sm:items-center sm:gap-6 sm:py-4 ..."><img class="mx-auto block h-24 rounded-full sm:mx-0 sm:shrink-0" src="/img/erin-lindford.jpg" alt="" /><div class="space-y-2 text-center sm:text-left">  <div class="space-y-0.5">    <p class="text-lg font-semibold text-black">Erin Lindford</p>    <p class="font-medium text-gray-500">Product Engineer</p>  </div>  <button class="border-purple-200 text-purple-600 hover:border-transparent hover:bg-purple-600 hover:text-white active:bg-purple-700 ...">    Message  </button></div></div>

在工具类中思考(Thinking in utility classes)

¥Thinking in utility classes

设置悬停和聚焦状态的样式(Styling hover and focus states)

¥Styling hover and focus states

要根据悬停或聚焦等状态来设置元素的样式,请在任何工具前加上你想要定位的状态,例如 hover:bg-sky-700

¥To style an element on states like hover or focus, prefix any utility with the state you want to target, for example hover:bg-sky-700:

悬停在此按钮上以查看背景颜色变化

<button class="bg-sky-500 hover:bg-sky-700 ...">Save changes</button>

这些前缀在 Tailwind 中称为 variants,并且仅当该变体的条件匹配时,它们才会应用工具类中的样式。

¥These prefixes are called variants in Tailwind, and they only apply the styles from a utility class when the condition for that variant matches.

以下是为 hover:bg-sky-700 类生成的 CSS 的样子:

¥Here's what the generated CSS looks like for the hover:bg-sky-700 class:

Generated CSS
.hover\:bg-sky-700 {  &:hover {    background-color: var(--color-sky-700);  }}

注意到这个类在元素悬停时不执行任何操作吗?它的唯一作用是提供悬停样式 — 没有其他用途。

¥Notice how this class does nothing unless the element is hovered? Its only job is to provide hover styles — nothing else.

这与你编写传统 CSS 的方式不同,在传统 CSS 中,单个类通常会提供许多状态的样式:

¥This is different from how you'd write traditional CSS, where a single class would usually provide the styles for many states:

HTML
<button class="btn">Save changes</button><style>  .btn {    background-color: var(--color-sky-500);    &:hover {      background-color: var(--color-sky-700);    }  }</style>

你甚至可以在 Tailwind 中堆叠变体以在多个条件匹配时应用工具,例如组合 hover:disabled:

¥You can even stack variants in Tailwind to apply a utility when multiple conditions match, like combining hover: and disabled:

<button class="bg-sky-500 disabled:hover:bg-sky-500 ...">Save changes</button>

悬停,聚焦和其他状态 的文档样式元素中了解更多信息。

¥Learn more in the documentation styling elements on hover, focus, and other states.

媒体查询和断点(Media queries and breakpoints)

¥Media queries and breakpoints

就像悬停和聚焦状态一样,你可以通过在任何工具前面加上要应用该样式的断点来为不同断点处的元素设置样式:

¥Just like hover and focus states, you can style elements at different breakpoints by prefixing any utility with the breakpoint where you want that style to apply:

调整此示例大小以查看布局变化

01
02
03
04
05
06
<div class="grid grid-cols-2 sm:grid-cols-3"><!-- ... --></div>

在上面的例子中,sm: 前缀确保 grid-cols-3 仅在 sm 断点及以上触发,即开箱即用的 40rem:

¥In the example above, the sm: prefix makes sure that grid-cols-3 only triggers at the sm breakpoint and above, which is 40rem out of the box:

Generated CSS
.sm\:grid-cols-3 {  @media (width >= 40rem) {    grid-template-columns: repeat(3, minmax(0, 1fr));  }}

响应式设计 文档中了解更多信息。

¥Learn more in the responsive design documentation.

定位夜间模式(Targeting dark mode)

¥Targeting dark mode

在夜间模式下设置元素的样式只需将 dark: 前缀添加到你想要在夜间模式处于活动状态时应用的任何工具即可:

¥Styling an element in dark mode is just a matter of adding the dark: prefix to any utility you want to apply when dark mode is active:

Light mode

Writes upside-down

The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.

Dark mode

Writes upside-down

The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.

<div class="bg-white dark:bg-gray-800 rounded-lg px-6 py-8 ring shadow-xl ring-gray-900/5"><div>  <span class="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg">    <svg      class="h-6 w-6 text-white"      fill="none"      viewBox="0 0 24 24"      stroke="currentColor"      aria-hidden="true"    >      <!-- ... -->    </svg>  </span></div><h3 class="text-gray-900 dark:text-white mt-5 text-base font-medium tracking-tight ">Writes upside-down</h3><p class="text-gray-500 dark:text-gray-400 mt-2 text-sm ">  The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.</p></div>

就像悬停状态或媒体查询一样,重要的是要理解单个工具类永远不会同时包含明暗样式 - 你可以使用多个类在夜间模式下设置样式,一个用于明夜间模式样式,另一个用于暗夜间模式样式。

¥Just like with hover states or media queries, the important thing to understand is that a single utility class will never include both the light and dark styles — you style things in dark mode by using multiple classes, one for the light mode styles and another for the dark mode styles.

Generated CSS
.dark\:bg-gray-800 {  @media (prefers-color-scheme: dark) {    background-color: var(--color-gray-800);  }}

夜间模式 文档中了解更多信息。

¥Learn more in the dark mode documentation.

使用类组合(Using class composition)

¥Using class composition

很多时候,使用 Tailwind 你甚至会使用多个类来构建单个 CSS 属性的值,例如向元素添加多个过滤:

¥A lot of the time with Tailwind you'll even use multiple classes to build up the value for a single CSS property, for example adding multiple filters to an element:

HTML
<div class="blur-sm grayscale">  <!-- ... --></div>

这两种效果都依赖于 CSS 中的 filter 属性,因此 Tailwind 使用 CSS 变量将这些效果组合在一起成为可能:

¥Both of these effects rely on the filter property in CSS, so Tailwind uses CSS variables to make it possible to compose these effects together:

Generated CSS
.blur-sm {  --tw-blur: blur(var(--blur-sm));  filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-grayscale,);}.grayscale {  --tw-grayscale: grayscale(100%);  filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-grayscale,);}

上面生成的 CSS 略有简化,但这里的技巧是每个工具都仅为其要应用的效果设置一个 CSS 变量。然后,filter 属性会查看所有这些变量,如果未设置变量,则返回为空。

¥The generated CSS above is slightly simplified, but the trick here is that each utility sets a CSS variable just for the effect it's meant to apply. Then the filter property looks at all of these variables, falling back to nothing if the variable hasn't been set.

Tailwind 对 gradients阴影颜色transforms 等使用相同的方法。

¥Tailwind uses this same approach for gradients, shadow colors, transforms, and more.

使用任意值(Using arbitrary values)

¥Using arbitrary values

Tailwind 中的许多工具都由 主题变量 驱动,例如 bg-blue-500text-xlshadow-md,它们映射到你的底层调色板、类型比例和阴影。

¥Many utilities in Tailwind are driven by theme variables, like bg-blue-500, text-xl, and shadow-md, which map to your underlying color palette, type scale, and shadows.

当你需要在主题之外使用一次性值时,请使用特殊的方括号语法来指定任意值:

¥When you need to use a one-off value outside of your theme, use the special square bracket syntax for specifying arbitrary values:

HTML
<button class="bg-[#316ff6] ...">  Sign in with Facebook</button>

这对于调色板之外的一次性颜色(如上面的 Facebook 蓝色)很有用,但当你需要复杂的自定义值(如非常具体的网格)时也很有用:

¥This can be useful for one-off colors outside of your color palette (like the Facebook blue above), but also when you need a complex custom value like a very specific grid:

HTML
<div class="grid grid-cols-[24rem_2.5rem_minmax(0,1fr)]">  <!-- ... --></div>

当你需要使用 CSS 功能(如 calc())时,即使你正在使用主题值,它也很有用:

¥It's also useful when you need to use CSS features like calc(), even if you are using your theme values:

HTML
<div class="max-h-[calc(100dvh-(--spacing(6))]">  <!-- ... --></div>

甚至还有一种语法可以生成完全任意的 CSS,包括任意属性名称,这对于设置 CSS 变量很有用:

¥There's even a syntax for generating completely arbitrary CSS including an arbitrary property name, which can be useful for setting CSS variables:

HTML
<div class="[--gutter-width:1rem] lg:[--gutter-width:2rem]">  <!-- ... --></div>

使用任意值 的文档中了解更多信息。

¥Learn more in the documentation on using arbitrary values.

这怎么起作用?(How does this even work?)

¥How does this even work?

Tailwind CSS 不是你可能习惯使用其他 CSS 框架的大型静态样式表 - 它根据你在编译 CSS 时实际使用的类生成所需的 CSS。

¥Tailwind CSS isn't one big static stylesheet like you might be used to with other CSS frameworks — it generates the CSS needed based on the classes you're actually using when you compile your CSS.

它通过扫描项目中的所有文件来查找任何看起来像是类名的符号来实现这一点:

¥It does this by scanning all of the files in your project looking for any symbol that looks like it could be a class name:

Button.jsx
export default function Button({ size, children }) {  let sizeClasses = {    md: "px-4 py-2 rounded-md text-base",    lg: "px-5 py-3 rounded-lg text-lg",  }[size];  return (    <button type="button" className={`font-bold ${sizeClasses}`}>      {children}    </button>  );}

找到所有潜在类后,Tailwind 会为每个类生成 CSS,并将其全部编译成一个仅包含你实际需要的样式的样式表。

¥After it's found all of the potential classes, Tailwind generates the CSS for each one and compiles it all into one stylesheet of just the styles you actually need.

由于 CSS 是基于类名生成的,因此 Tailwind 可以使用任意值(如 bg-[#316ff6])识别类并生成必要的 CSS,即使该值不是主题的一部分。

¥Since the CSS is generated based on the class name, Tailwind can recognize classes using arbitrary values like bg-[#316ff6] and generate the necessary CSS, even when the value isn't part of your theme.

了解有关其在 检测源文件中的类 中的工作原理的更多信息。

¥Learn more about how this works in detecting classes in source files.

复杂选择器(Complex selectors)

¥Complex selectors

有时你需要在多种条件下设置元素的样式,例如在夜间模式下、在特定断点处、悬停时以及当元素具有特定数据属性时。

¥Sometimes you need to style an element under a combination of conditions, for example in dark mode, at a specific breakpoint, when hovered, and when the element has a specific data attribute.

以下是使用 Tailwind 的示例:

¥Here's an example of what that looks like with Tailwind:

HTML
<button class="dark:lg:data-current:hover:bg-indigo-600 ..."><!-- ... --></button>
Simplified CSS
@media (prefers-color-scheme: dark) and (width >= 64rem) {  button[data-current]:hover {    background-color: var(--color-indigo-600);  }}

Tailwind 还支持 group-hover 之类的功能,当鼠标悬停在特定父元素上时,你可以设置元素的样式:

¥Tailwind also supports things like group-hover, which let you style an element when a specific parent is hovered:

HTML
<a href="#" class="group rounded-lg p-8"><!-- ... --><span class="group-hover:underline">Read more…</span></a>
Simplified CSS
@media (hover: hover) {  a:hover span {    text-decoration-line: underline;  }}

group-* 语法也适用于其他变体,如 group-focusgroup-active更多

¥This group-* syntax works with other variants too, like group-focus, group-active, and many more.

对于非常复杂的场景(尤其是在设计你无法控制的 HTML 样式时),Tailwind 支持 任意变体,它允许你直接在类名中编写任何你想要的选择器:

¥For really complex scenarios (especially when styling HTML you don't control), Tailwind supports arbitrary variants which let you write any selector you want, directly in a class name:

HTML
<div class="[&>[data-active]+span]:text-blue-600 ..."><span data-active><!-- ... --></span><span>This text will be blue</span></div>
Simplified CSS
div > [data-active] + span {  color: var(--color-blue-600);}

何时使用内联样式(When to use inline styles)

¥When to use inline styles

内联样式在 Tailwind CSS 项目中仍然非常有用,特别是当值来自数据库或 API 等动态源时:

¥Inline styles are still very useful in Tailwind CSS projects, particularly when a value is coming from a dynamic source like a database or API:

branded-button.jsx
export function BrandedButton({ buttonColor, textColor, children }) {  return (    <button      style={{        backgroundColor: buttonColor,        color: textColor,      }}      className="rounded-md px-3 py-1.5 font-medium"    >      {children}    </button>  );}

对于非常复杂的任意值,你可能还会使用内联样式,这些值在格式化为类名时难以阅读:

¥You might also reach for an inline style for very complicated arbitrary values that are difficult to read when formatted as a class name:

HTML
<div class="grid-[2fr_max(0,var(--gutter-width))_calc(var(--gutter-width)+10px)]"><div style="grid-template-columns: 2fr max(0, var(--gutter-width)) calc(var(--gutter-width) + 10px)">  <!-- ... --></div>

另一个有用的模式是使用内联样式根据动态源设置 CSS 变量,然后使用工具类引用这些变量:

¥Another useful pattern is setting CSS variables based on dynamic sources using inline styles, then referencing those variables with utility classes:

branded-button.jsx
export function BrandedButton({ buttonColor, buttonColorHover, textColor, children }) {  return (    <button      style={{        "--bg-color": buttonColor,        "--bg-color-hover": buttonColorHover,        "--text-color": textColor,      }}      className="bg-(--bg-color) text-(--text-color) hover:bg-(--bg-color-hover) ..."    >      {children}    </button>  );}

管理重复(Managing duplication)

¥Managing duplication

当你仅使用工具类构建整个项目时,你不可避免地会发现自己重复某些模式以在不同位置重新创建相同的设计。

¥When you build entire projects with just utility classes, you'll inevitably find yourself repeating certain patterns to recreate the same design in different places.

例如,这里每个头像图片的工具类重复了五次:

¥For example, here the utility classes for each avatar image are repeated five separate times:

<div><div class="flex items-center space-x-2 text-base">  <h4 class="font-semibold text-slate-900">Contributors</h4>  <span class="bg-slate-100 px-2 py-1 text-xs font-semibold text-slate-700 ...">204</span></div><div class="mt-3 flex -space-x-2 overflow-hidden">  <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1491528323818-fdd1faba62cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="" />  <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="" />  <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2.25&w=256&h=256&q=80" alt="" />  <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="" />  <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src="https://images.unsplash.com/photo-1517365830460-955ce3ccd263?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="" /></div><div class="mt-3 text-sm font-medium">  <a href="#" class="text-blue-500">+ 198 others</a></div></div>

不要恐慌!实际上,这并不是你可能担心的问题,处理它的策略是你每天都在做的事情。

¥Don't panic! In practice this isn't the problem you might be worried it is, and the strategies for dealing with it are things you already do every day.

使用循环(Using loops)

¥Using loops

很多时候,在渲染页面中多次出现的设计元素实际上只创作了一次,因为实际标记是在循环中渲染的。

¥A lot of the time a design element that shows up more than once in the rendered page is only actually authored once because the actual markup is rendered in a loop.

例如,本指南开头的重复头像几乎肯定会在真实项目中循环渲染:

¥For example, the duplicate avatars at the beginning of this guide would almost certainly be rendered in a loop in a real project:

<div>  <div class="flex items-center space-x-2 text-base">    <h4 class="font-semibold text-slate-900">Contributors</h4>    <span class="bg-slate-100 px-2 py-1 text-xs font-semibold text-slate-700 ...">204</span>  </div>  <div class="mt-3 flex -space-x-2 overflow-hidden">    {#each contributors as user}      <img class="inline-block h-12 w-12 rounded-full ring-2 ring-white" src={user.avatarUrl} alt={user.handle} />    {/each}  </div>  <div class="mt-3 text-sm font-medium">    <a href="#" class="text-blue-500">+ 198 others</a>  </div></div>

当元素在这样的循环中渲染时,实际的类列表只被写入一次,因此没有实际的重复问题需要解决。

¥When elements are rendered in a loop like this, the actual class list is only written once so there's no actual duplication problem to solve.

使用多光标编辑(Using multi-cursor editing)

¥Using multi-cursor editing

当重复局限于单个文件中的一组元素时,最简单的处理方法是使用 多光标编辑 快速选择并一次编辑每个元素的类列表:

¥When duplication is localized to a group of elements in a single file, the easiest way to deal with it is to use multi-cursor editing to quickly select and edit the class list for each element at once:

你会惊讶于这最终成为最佳解决方案的频率。如果你可以同时快速编辑所有重复的类列表,那么引入任何额外的抽象就没有任何好处。

¥You'd be surprised at how often this ends up being the best solution. If you can quickly edit all of the duplicated class lists simultaneously, there's no benefit to introducing any additional abstraction.

<nav class="flex justify-center space-x-4">  <a href="/dashboard" class="font-medium rounded-lg px-3 py-2 text-gray-700 hover:bg-gray-100 hover:text-gray-900">    Home  </a>  <a href="/team" class="font-medium rounded-lg px-3 py-2 text-gray-700 hover:bg-gray-100 hover:text-gray-900">    Team  </a>  <a href="/projects" class="font-medium rounded-lg px-3 py-2 text-gray-700 hover:bg-gray-100 hover:text-gray-900">    Projects  </a>  <a href="/reports" class="font-medium rounded-lg px-3 py-2 text-gray-700 hover:bg-gray-100 hover:text-gray-900">    Reports  </a></nav>

使用组件(Using components)

¥Using components

如果你需要在多个文件中重用某些样式,最好的策略是创建一个组件(如果你使用的是 React、Svelte 或 Vue 等前端框架),或者如果你使用的是模板语言(例如 Blade、ERB、Twig 或 Nunjucks。

¥If you need to reuse some styles across multiple files, the best strategy is to create a component if you're using a front-end framework like React, Svelte, or Vue, or a template partial if you're using a templating language like Blade, ERB, Twig, or Nunjucks.

Beach
Private Villa
$299 USD per night
export function VacationCard({ img, imgAlt, eyebrow, title, pricing, url }) {  return (    <div>      <img className="rounded-lg" src={img} alt={imgAlt} />      <div className="mt-4">        <div className="text-xs font-bold text-sky-500">{eyebrow}</div>        <div className="mt-1 font-bold text-gray-700">          <a href={url} className="hover:underline">            {title}          </a>        </div>        <div className="mt-2 text-sm text-gray-600">{pricing}</div>      </div>    </div>  );}

现在,你可以在任意多个地方使用该组件,同时仍然拥有样式的单一真实来源,因此可以轻松地在一个地方一起更新它们。

¥Now you can use this component in as many places as you like, while still having a single source of truth for the styles so they can easily be updated together in one place.

使用自定义 CSS(Using custom CSS)

¥Using custom CSS

如果你使用的是模板语言(如 ERB 或 Twig),而不是 React 或 Vue 之类的语言,那么与像 btn 这样的简单 CSS 类相比,为按钮这样小的东西创建模板部分可能会感觉有点小题大做。

¥If you're using a templating language like ERB or Twig instead of something like React or Vue, creating a template partial for something as small as a button can feel like overkill compared to a simple CSS class like btn.

虽然强烈建议你为更复杂的组件创建适当的模板部分,但当模板部分感觉过于繁琐时,编写一些自定义 CSS 是完全没问题的。

¥While it's highly recommended that you create proper template partials for more complex components, writing some custom CSS is totally fine when a template partial feels heavy-handed.

以下是 btn-primary 类可能的样子,使用 主题变量 保持设计一致性:

¥Here's what a btn-primary class might look like, using theme variables to keep the design consistent:

HTML
<button class="btn-primary">Save changes</button>
CSS
@import "tailwindcss";@layer components {  .btn-primary {    border-radius: calc(infinity * 1px);    background-color: var(--color-violet-500);    padding-inline: --spacing(5);    padding-block: --spacing(2);    font-weight: var(--font-weight-semibold);    color: var(--color-white);    box-shadow: var(--shadow-md);    &:hover {      @media (hover: hover) {        background-color: var(--color-violet-700);      }    }  }}

不过,对于任何比单个 HTML 元素更复杂的东西,我们强烈建议使用模板部分,以便样式和结构可以封装在一个地方。

¥Again though, for anything that's more complicated than just a single HTML element, we highly recommend using template partials so the styles and structure can be encapsulated in one place.

管理样式冲突(Managing style conflicts)

¥Managing style conflicts

冲突的工具类(Conflicting utility classes)

¥Conflicting utility classes

添加两个针对相同 CSS 属性的类时,样式表中较晚出现的类将获胜。因此,在此示例中,即使 flex 在实际 class 属性中排在最后,元素也会接收 display: grid

¥When you add two classes that target the same CSS property, the class that appears later in the stylesheet wins. So in this example, the element will receive display: grid even though flex comes last in the actual class attribute:

HTML
<div class="grid flex"><!-- ... --></div>
CSS
.flex {  display: flex;}.grid {  display: grid;}

一般来说,你永远不应该向同一个元素添加两个冲突的类 - 只添加你真正希望生效的类:

¥In general, you should just never add two conflicting classes to the same element — only ever add the one you actually want to take effect:

example.jsx
export function Example({ gridLayout }) {  return <div className={gridLayout ? "grid" : "flex"}>{/* ... */}</div>;}

使用基于组件的库(如 React 或 Vue),这通常意味着公开特定的 props 以进行样式自定义,而不是让消费者从组件外部添加额外的类,因为这些样式通常会发生冲突。

¥Using component-based libraries like React or Vue, this often means exposing specific props for styling customizations instead of letting consumers add extra classes from outside of a component, since those styles will often conflict.

使用 important 修饰符(Using the important modifier)

¥Using the important modifier

当你确实需要强制特定工具类生效并且没有其他方法来管理特异性时,你可以在类名末尾添加 ! 以使所有声明都成为 !important

¥When you really need to force a specific utility class to take effect and have no other means of managing the specificity, you can add ! to the end of the class name to make all of the declarations !important:

HTML
<div class="bg-teal-500 bg-red-500!"><!-- ... --></div>
Generated CSS
.bg-red-500\! {  background-color: var(--color-red-500) !important;}.bg-teal-500 {  background-color: var(--color-teal-500);}

使用 important 标志(Using the important flag)

¥Using the important flag

如果你将 Tailwind 添加到具有高特异性规则的现有复杂 CSS 的项目中,则可以在导入 Tailwind 时使用 important 标志将所有工具标记为 !important

¥If you're adding Tailwind to a project that has existing complex CSS with high specificity rules, you can use the important flag when importing Tailwind to mark all utilities as !important:

app.css
@import "tailwindcss" important;
Compiled CSS
@layer utilities {  .flex {    display: flex !important;  }  .gap-4 {    gap: 1rem !important;  }  .underline {    text-decoration-line: underline !important;  }}

使用前缀选项(Using the prefix option)

¥Using the prefix option

如果你的项目有与 Tailwind CSS 工具冲突的类名,你可以使用 prefix 选项为所有 Tailwind 生成的类和 CSS 变量添加前缀:

¥If your project has class names that conflict with Tailwind CSS utilities, you can prefix all Tailwind-generated classes and CSS variables using the prefix option:

app.css
@import "tailwindcss" prefix(tw);
Compiled CSS
@layer theme {  :root {    --tw-color-red-500: oklch(0.637 0.237 25.331);  }}@layer utilities {  .tw\:text-red-500 {    color: var(--tw-color-red-500);  }}
TailwindCSS v4.0 中文网 - 粤ICP备13048890号