1. 核心概念
  2. 悬停、聚焦及其他状态

核心概念

悬停、焦点和其他状态

使用工具类来设置元素在悬停、焦点等状态下的样式。

Tailwind 中的每个工具类都可以通过_条件性_应用,只需在类名前添加描述目标状态的变体即可。

例如,要在悬停时应用 bg-sky-700 类,使用 hover:bg-sky-700 类:

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

<button class="bg-sky-500 hover:bg-sky-700 ...">保存更改</button>
这与传统 CSS 有何不同?

传统编写 CSS 时,单个类名会根据当前状态执行不同的操作:

传统方式中同一个类名在悬停时应用不同样式

.btn-primary {  background-color: #0ea5e9;}.btn-primary:hover {  background-color: #0369a1;}

在 Tailwind 中,不是向现有类添加悬停状态样式,而是向元素添加另一个_仅_在悬停时生效的类:

Tailwind 中默认状态和悬停状态使用不同的类

.bg-sky-500 {  background-color: #0ea5e9;}.hover\:bg-sky-700:hover {  background-color: #0369a1;}

注意 hover:bg-sky-700 _仅_为 :hover 状态定义样式?默认情况下它不执行任何操作,但当你悬停带有该类的元素时,背景色会变为 sky-700

这就是我们所说的工具类可以_条件性_应用——通过使用变体,你可以精确控制设计在不同状态下的表现,而无需离开 HTML。

Tailwind 包含了几乎所有你可能需要的变体,包括:

这些变体甚至可以堆叠以针对更具体的情况,例如在深色模式、中等断点、悬停时改变背景色:

<button class="dark:md:hover:bg-fuchsia-600 ...">保存更改</button>

在本指南中,你将了解框架中可用的所有变体,如何将它们与你自定义的类一起使用,甚至如何创建你自己的变体。

伪类

:hover、:focus 和 :active

使用 hoverfocusactive 变体来设置元素在悬停、聚焦和激活状态下的样式:

尝试与这个按钮交互,查看悬停、聚焦和激活状态

<button class="bg-violet-500 hover:bg-violet-600 focus:outline-2 focus:outline-offset-2 focus:outline-violet-500 active:bg-violet-700 ...">  保存更改</button>

Tailwind 还包含其他交互状态的变体,如 :visited:focus-within:focus-visible 等。

查看 伪类参考 获取完整的可用伪类变体列表。

:first, :last, :odd 和 :even

使用 firstlast 变体来设置元素作为第一个或最后一个子元素时的样式:

  • Kristen Ramos

    kristen.ramos@example.com

  • Floyd Miles

    floyd.miles@example.com

  • Courtney Henry

    courtney.henry@example.com

  • Ted Fox

    ted.fox@example.com

<ul role="list">  {#each people as person}    <!-- 当是第一个/最后一个子元素时移除顶部/底部内边距 -->    <li class="flex py-4 first:pt-0 last:pb-0">      <img class="h-10 w-10 rounded-full" src={person.imageUrl} alt="" />      <div class="ml-3 overflow-hidden">        <p class="text-sm font-medium text-gray-900 dark:text-white">{person.name}</p>        <p class="truncate text-sm text-gray-500 dark:text-gray-400">{person.email}</p>      </div>    </li>  {/each}</ul>

你也可以使用 oddeven 变体来设置奇数或偶数字元素的样式:

姓名职位邮箱
Jane Cooper区域范式技术员jane.cooper@example.com
Cody Fisher产品指令官cody.fisher@example.com
Leonard Krasner高级设计师leonard.krasner@example.com
Emily Selman硬件工程副总裁emily.selman@example.com
Anna Roberts首席战略官anna.roberts@example.com
<table>  <!-- ... -->  <tbody>    {#each people as person}      <!-- 为奇数和偶数行使用不同的背景色 -->      <tr class="odd:bg-white even:bg-gray-50 dark:odd:bg-gray-900/50 dark:even:bg-gray-950">        <td>{person.name}</td>        <td>{person.title}</td>        <td>{person.email}</td>      </tr>    {/each}  </tbody></table>

使用 nth-*nth-last-* 变体根据元素在列表中的位置来设置样式:

<div class="nth-3:underline">  <!-- ... --></div><div class="nth-last-5:underline">  <!-- ... --></div><div class="nth-of-type-4:underline">  <!-- ... --></div><div class="nth-last-of-type-6:underline">  <!-- ... --></div>

默认情况下你可以传入任何数字,对于更复杂的表达式如 nth-[2n+1_of_li] 可以使用任意值。

Tailwind 还包含其他结构性伪类变体,如 :only-child:first-of-type:empty 等。

查看 伪类参考 获取完整的可用伪类变体列表。

:required 和 :disabled

使用 requiredinvaliddisabled 等变体来为不同状态的表单元素设置样式:

尝试输入有效的电子邮件地址以查看样式变化

<input  type="text"  value="tbone"  disabled  class="invalid:border-pink-500 invalid:text-pink-600 focus:border-sky-500 focus:outline focus:outline-sky-500 focus:invalid:border-pink-500 focus:invalid:outline-pink-500 disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none dark:disabled:border-gray-700 dark:disabled:bg-gray-800/20 ..."/>

使用这类变体可以减少模板中的条件逻辑,让你无论输入框处于什么状态都能使用相同的类集合,而由浏览器为你应用正确的样式。

Tailwind 还包含其他表单状态变体,如 :read-only:indeterminate:checked 等。

完整可用的伪类变体列表请参阅 伪类参考

:has()

使用 has-* 变体可以根据后代元素的状态或内容来设置样式:

支付方式
<label  class="has-checked:bg-indigo-50 has-checked:text-indigo-900 has-checked:ring-indigo-200 dark:has-checked:bg-indigo-950 dark:has-checked:text-indigo-200 dark:has-checked:ring-indigo-900 ...">  <svg fill="currentColor">    <!-- ... -->  </svg>  Google Pay  <input type="radio" class="checked:border-indigo-500 ..." /></label>

你可以使用带有伪类的 has-*,例如 has-[:focus],根据其后代元素的状态来设置样式。同样,你也可以使用元素选择器,如 has-[img]has-[a],根据其后代元素的内容来设置样式。

基于父元素后代进行样式设置

如果需要根据父元素的后代元素来设置样式,可以在父元素上添加 group 类,然后使用 group-has-* 变体来设置目标元素的样式:

Spencer Sharp

Product Designer at planeteria.tech

Casey Jordan

Just happy to be here.

Alex Reed

A multidisciplinary designer, working at the intersection of art and technology.

alex-reed.com

Taylor Bailey

Pushing pixels. Slinging divs.

<div class="group ...">  <img src="..." />  <h4>Spencer Sharp</h4>  <svg class="hidden group-has-[a]:block ..."><!-- ... --></svg>  <p>Product Designer at <a href="...">planeteria.tech</a></p></div>

基于同级元素后代进行样式设置

如果需要根据同级元素的后代元素来设置样式,可以使用 peer 类标记该同级元素,然后使用 peer-has-* 变体来设置目标元素的样式:

今日任务
<div>  <label class="peer ...">    <input type="checkbox" name="todo[1]" checked />    创建待办清单  </label>  <svg class="peer-has-checked:hidden ..."><!-- ... --></svg></div>

:not()

使用 not- 变体在条件不成立时为元素添加样式。

当与其他伪类变体结合使用时尤其强大,例如将 not-focus:hover: 结合,仅在元素未获得焦点时应用悬停样式:

尝试聚焦按钮然后悬停在它上方

<button class="bg-indigo-600 hover:not-focus:bg-indigo-700">  <!-- ... --></button>

你也可以将 not- 变体与媒体查询变体如 forced-colorssupports 结合,仅在用户环境条件不成立时设置元素样式:

<div class="not-supports-[display:grid]:flex">  <!-- ... --></div>

基于父元素状态的样式设置

当你需要根据某个_父元素_的状态来设置子元素的样式时,可以给父元素添加 group 类,然后使用 group-* 变体(如 group-hover)来设置目标元素的样式:

悬停在卡片上可以看到两个文本元素的颜色变化

<a href="#" class="group ...">  <div>    <svg class="stroke-sky-500 group-hover:stroke-white ..." fill="none" viewBox="0 0 24 24">      <!-- ... -->    </svg>    <h3 class="text-gray-900 group-hover:text-white ...">新建项目</h3>  </div>  <p class="text-gray-500 group-hover:text-white ...">从多种起始模板创建新项目。</p></a>

这种模式适用于所有伪类变体,例如 group-focusgroup-active,甚至是 group-odd

区分嵌套群组

当嵌套群组时,您可以通过给父群组一个唯一的群组名称(使用 group/{name} 类),并在变体类中包含该名称(如 group-hover/{name}),来基于特定父群组的状态设置样式:

<ul role="list">  {#each people as person}    <li class="group/item ...">      <!-- ... -->      <a class="group/edit invisible group-hover/item:visible ..." href="tel:{person.phone}">        <span class="group-hover/edit:text-gray-700 ...">呼叫</span>        <svg class="group-hover/edit:translate-x-0.5 group-hover/edit:text-gray-500 ..."><!-- ... --></svg>      </a>    </li>  {/each}</ul>

群组可以随意命名,无需任何配置 - 只需在标记中直接命名您的群组,Tailwind 将自动生成必要的 CSS。

任意分组

你可以通过在中括号内提供自定义选择器作为任意值,即时创建一次性的 group-* 变体:

<div class="group is-published">  <div class="hidden group-[.is-published]:block">    已发布  </div></div>

为了更精细的控制,你可以使用 & 字符来标记 .group 在最终选择器中相对于你传入的选择器的位置:

<div class="group">  <div class="group-[:nth-of-type(3)_&]:block">    <!-- ... -->  </div></div>

隐式分组

in-* 变体的工作方式与 group 类似,只是你不需要在父元素上添加 group 类:

<div tabindex="0" class="group">  <div class="opacity-50 group-focus:opacity-100"><div tabindex="0">  <div class="opacity-50 in-focus:opacity-100">    <!-- ... -->  </div></div>

in-* 变体会响应任何父元素的状态变化,因此如果你需要更精细的控制,还是需要使用 group

基于兄弟元素状态的样式设置

当需要根据 兄弟 元素的状态来设置样式时,可以使用 peer 类标记兄弟元素,然后使用 peer-* 变体(如 peer-invalid)来设置目标元素的样式:

尝试输入有效的电子邮件地址使警告消失

<form>  <label class="block">    <span class="...">电子邮件</span>    <input type="email" class="peer ..." />    <p class="invisible peer-invalid:visible ...">请输入有效的电子邮件地址。</p>  </label></form>

这使得可以实现各种巧妙的效果,例如浮动标签,而无需任何 JavaScript。

这种模式适用于所有伪类变体,例如 peer-focuspeer-requiredpeer-disabled

需要注意的是,由于 CSS 中后续兄弟组合器的工作原理,peer 标记只能用于 前面的 兄弟元素:

不会生效,只有前面的兄弟元素才能被标记为 peer

<label>  <span class="peer-invalid:text-red-500 ...">电子邮件</span>  <input type="email" class="peer ..." /></label>

区分同级元素

当使用多个同级元素时,你可以通过为特定同级元素添加 peer/{name} 类来赋予其唯一名称,然后使用像 peer-checked/{name} 这样的变体类来根据该特定同级元素的状态设置样式:

发布状态
<fieldset>  <legend>发布状态</legend>  <input id="draft" class="peer/draft" type="radio" name="status" checked />  <label for="draft" class="peer-checked/draft:text-sky-500">草稿</label>  <input id="published" class="peer/published" type="radio" name="status" />  <label for="published" class="peer-checked/published:text-sky-500">已发布</label>  <div class="hidden peer-checked/draft:block">草稿仅对管理员可见。</div>  <div class="hidden peer-checked/published:block">您的文章将在您的网站上公开可见。</div></fieldset>

同级元素的命名可以完全自定义,无需任何额外配置——只需在标记中直接命名你的同级元素,Tailwind 就会自动生成必要的 CSS。

任意同级选择器

你可以通过在中括号内提供自定义选择器作为任意值,即时创建一次性的 peer-* 变体:

<form>  <label for="email">邮箱:</label>  <input id="email" name="email" type="email" class="is-dirty peer" required />  <div class="peer-[.is-dirty]:peer-required:block hidden">此字段为必填项。</div>  <!-- ... --></form>

如需更精细的控制,可以使用 & 字符来标记 .peer 在最终选择器中相对于你传入的选择器应出现的位置:

<div>  <input type="text" class="peer" />  <div class="hidden peer-[:nth-of-type(3)_&]:block">    <!-- ... -->  </div></div>

伪元素

::before 和 ::after

使用 beforeafter 变体来设置 ::before::after 伪元素的样式:

<label>  <span class="text-gray-700 after:ml-0.5 after:text-red-500 after:content-['*'] ...">邮箱</span>  <input type="email" name="email" class="..." placeholder="you@example.com" /></label>

使用这些变体时,Tailwind 会自动默认添加 content: '',因此除非你需要不同的值,否则无需特别指定:

当你总是看起来 很烦恼 时,人们会认为你很忙。
<blockquote class="text-center text-2xl font-semibold text-gray-900 italic dark:text-white">  当你看起来  <span class="relative inline-block before:absolute before:-inset-1 before:block before:-skew-y-3 before:bg-pink-500">    <span class="relative text-white dark:text-gray-950">很烦恼</span>  </span>  时,人们会认为你很忙。</blockquote>

值得注意的是,在大多数 Tailwind 项目中,你并不真正需要 ::before::after 伪元素——通常使用真实的 HTML 元素会更简单。

例如,下面是相同的设计,但使用 <span> 替代 ::before 伪元素,这样更易读且代码量更少:

<blockquote class="text-center text-2xl font-semibold text-gray-900 italic">  当你看起来  <span class="relative">    <span class="absolute -inset-1 block -skew-y-3 bg-pink-500" aria-hidden="true"></span>    <span class="relative text-white">很烦恼</span>  </span>  时,人们会认为你很忙。</blockquote>

beforeafter 保留用于那些伪元素内容不在 DOM 中且不能被用户选择的重要场景。

::placeholder

使用 placeholder 变体来设置任何输入框或文本域的占位文本样式:

<input  class="placeholder:text-gray-500 placeholder:italic ..."  placeholder="Search for anything..."  type="text"  name="search"/>

::file

使用 file 变体来样式化文件输入框中的按钮:

当前个人资料照片
<input  type="file"  class="file:mr-4 file:rounded-full file:border-0 file:bg-violet-50 file:px-4 file:py-2 file:text-sm file:font-semibold file:text-violet-700 hover:file:bg-violet-100 dark:file:bg-violet-600 dark:file:text-violet-100 dark:hover:file:bg-violet-500 ..."/>

::marker

使用 marker 变体来设置列表中的计数器或项目符号样式:

食材

  • 5杯切好的牛肝菌
  • 1/2杯橄榄油
  • 3磅芹菜
<ul role="list" class="list-disc marker:text-sky-400 ...">  <li>5 cups chopped Porcini mushrooms</li>  <li>1/2 cup of olive oil</li>  <li>3lb of celery</li></ul>

我们将 marker 变体设计为可继承的,因此虽然你可以直接在 <li> 元素上使用它,但也可以在父元素上使用以避免重复代码。

::selection

使用 selection 变体来设置选中文本的样式:

尝试用鼠标选中部分文本

于是我开始走向水中。孩子们,我不会骗你们,我当时害怕极了。但我坚持前进,当我穿过浪花时,一种奇怪的平静笼罩了我。我不知道这是神的干预还是所有生物的共鸣,但杰瑞,我要告诉你,在那一刻,我就是一名海洋生物学家。

<div class="selection:bg-fuchsia-300 selection:text-fuchsia-900">  <p>    于是我开始走向水中。孩子们,我不会骗你们,我当时害怕极了。但我坚持前进,当我穿过浪花时,一种奇怪的平静笼罩了我。我不知道这是神的干预还是所有生物的共鸣,但杰瑞,我要告诉你,在那一刻,我<em>就是</em>一名海洋生物学家。  </p></div>

我们将 selection 变体设计为可继承的,因此您可以将其添加到树中的任何位置,它会应用于所有后代元素。

这使得您可以轻松地为整个网站设置与品牌匹配的选中颜色:

<html>  <head>    <!-- ... -->  </head>  <body class="selection:bg-pink-300">    <!-- ... -->  </body></html>

::first-line 和 ::first-letter 伪元素

使用 first-line 变体可以设置内容块中首行的样式,使用 first-letter 变体可以设置首字母的样式:

Well, let me tell you something, funny boy. Y'know that little stamp, the one that says "New York Public Library"? Well that may not mean anything to you, but that means a lot to me. One whole hell of a lot.

Sure, go ahead, laugh if you want to. I've seen your type before: Flashy, making the scene, flaunting convention. Yeah, I know what you're thinking. What's this guy making such a big stink about old library books? Well, let me give you a hint, junior.

<div class="text-gray-700">  <p    class="first-letter:float-left first-letter:mr-3 first-letter:text-7xl first-letter:font-bold first-letter:text-gray-900 first-line:tracking-widest first-line:uppercase"  >    Well, let me tell you something, funny boy. Y'know that little stamp, the one that says "New York Public Library"?  </p>  <p class="mt-6">Well that may not mean anything to you, but that means a lot to me. One whole hell of a lot.</p></div>

::backdrop

使用 backdrop 变体来样式化原生 <dialog> 元素的背景层:

<dialog class="backdrop:bg-gray-50">  <form method="dialog">    <!-- ... -->  </form></dialog>

如果你在项目中使用原生 <dialog> 元素,可能还需要了解如何使用 open 变体来样式化打开/关闭状态

媒体查询与特性查询

响应式断点

要在特定断点处样式化元素,请使用响应式变体如 mdlg

例如,这将在移动设备上渲染 3 列网格,中等宽度屏幕上渲染 4 列网格,大宽度屏幕上渲染 6 列网格:

<div class="grid grid-cols-3 md:grid-cols-4 lg:grid-cols-6">  <!-- ... --></div>

要根据父元素宽度而非视口宽度样式化元素,请使用 @md@lg 等变体:

<div class="@container">  <div class="flex flex-col @md:flex-row">    <!-- ... -->  </div></div>

查看响应式设计文档深入了解这些功能的工作原理。

prefers-color-scheme

prefers-color-scheme 媒体查询可以检测用户偏好的是浅色主题还是深色主题,这一偏好通常是在操作系统层面配置的。

使用无变体的工具类来针对浅色模式,使用 dark 变体来为深色模式提供样式覆盖:

浅色模式

倒立书写

零重力笔可以在任何方向书写,包括倒立书写。它甚至在外太空也能使用。

深色模式

倒立书写

零重力笔可以在任何方向书写,包括倒立书写。它甚至在外太空也能使用。

<div class="bg-white dark:bg-gray-900 ...">  <!-- ... -->  <h3 class="text-gray-900 dark:text-white ...">倒立书写</h3>  <p class="text-gray-500 dark:text-gray-400 ...">    零重力笔可以在任何方向书写,包括倒立书写。它甚至在外太空也能使用。  </p></div>

查看深色模式文档深入了解这一功能的工作原理。

prefers-reduced-motion

prefers-reduced-motion 媒体查询可以检测用户是否请求减少非必要的动画效果。

使用 motion-reduce 变体可以在用户请求减少动画时条件性地添加样式:

尝试在开发者工具中模拟 `prefers-reduced-motion: reduce` 来隐藏旋转图标

<button type="button" class="bg-indigo-500 ..." disabled>  <svg class="animate-spin motion-reduce:hidden ..." viewBox="0 0 24 24"><!-- ... --></svg>  处理中...</button>

Tailwind 还包含一个 motion-safe 变体,它仅在用户_没有_请求减少动画时添加样式。当使用 motion-reduce 辅助类意味着需要"撤销"大量样式时,这会很有用:

<!-- 使用 `motion-reduce` 可能意味着需要大量"撤销"样式 --><button class="transition hover:-translate-y-0.5 motion-reduce:transition-none motion-reduce:hover:translate-y-0 ...">  保存更改</button><!-- 在这些情况下使用 `motion-safe` 代码更少 --><button class="motion-safe:transition motion-safe:hover:-translate-x-0.5 ...">保存更改</button>

prefers-contrast

prefers-contrast 媒体查询可以检测用户是否请求了更高或更低的对比度。

使用 contrast-more 变体可以在用户请求更高对比度时条件性地添加样式:

尝试在开发者工具中模拟 `prefers-contrast: more` 来查看变化

我们需要这个来窃取您的身份。

<label class="block">  <span class="block text-sm font-medium text-gray-700">社会保障号码</span>  <input    class="border-gray-200 placeholder-gray-400 contrast-more:border-gray-400 contrast-more:placeholder-gray-500 ..."  />  <p class="text-gray-600 opacity-10 contrast-more:opacity-100 ...">我们需要这个来窃取您的身份。</p></label>

Tailwind 还包含一个 contrast-less 变体,可以在用户请求更低对比度时条件性地添加样式。

forced-colors

forced-colors 媒体查询用于检测用户是否启用了强制色彩模式。这些模式会用用户定义的调色板覆盖您网站的文字、背景、链接和按钮颜色。

使用 forced-colors 变体可以在用户启用强制色彩模式时有条件地添加样式:

尝试在开发者工具中模拟 `forced-colors: active` 来查看变化

选择主题:
<label>  <input type="radio" class="appearance-none forced-colors:appearance-auto" />  <p class="hidden forced-colors:block">青色</p>  <div class="bg-cyan-200 forced-colors:hidden ..."></div>  <div class="bg-cyan-500 forced-colors:hidden ..."></div></label>

使用 not-forced-colors 变体可以在用户_未_使用强制色彩模式时应用样式:

<div class="not-forced-colors:appearance-none ...">  <!-- ... --></div>

Tailwind 还包含 forced color adjust 工具类,用于选择是否参与强制色彩调整。

inverted-colors

使用 inverted-colors 变体可以在用户启用反色模式时条件性地添加样式:

<div class="shadow-xl inverted-colors:shadow-none ...">  <!-- ... --></div>

pointer 和 any-pointer

pointer 媒体查询可以判断用户是否拥有主要指向设备(如鼠标)以及该设备的精确度。

使用 pointer-fine 变体来针对精确的指向设备(如鼠标或触控板),或使用 pointer-coarse 变体来针对不太精确的指向设备(如触摸屏),这在为触摸设备提供更大的点击目标时非常有用:

尝试在开发者工具中模拟触摸设备以查看变化

<fieldset aria-label="选择内存选项">  <div class="flex items-center justify-between">    <div>内存</div>    <a href="#"> 查看性能规格 </a>  </div>  <div class="mt-4 grid grid-cols-6 gap-2 pointer-coarse:mt-6 pointer-coarse:grid-cols-3 pointer-coarse:gap-4">    <label class="p-2 pointer-coarse:p-4 ...">      <input type="radio" name="memory-option" value="4 GB" className="sr-only" />      <span>4 GB</span>    </label>    <!-- ... -->  </div></fieldset>

pointer 仅针对主要指向设备,而 any-pointer 则用于针对任何可能可用的指向设备。使用 any-pointer-fineany-pointer-coarse 变体可以在至少一个连接的指向设备符合条件时提供不同的样式。

你可以使用 pointer-noneany-pointer-none 来针对没有指向设备的情况。

屏幕方向

使用 portraitlandscape 变体来根据视口方向条件性地添加样式:

<div>  <div class="portrait:hidden">    <!-- ... -->  </div>  <div class="landscape:hidden">    <p>此体验设计为横屏查看。请旋转您的设备以浏览网站。</p>  </div></div>

脚本支持

使用 noscript 变体来根据用户是否启用了脚本(如 JavaScript)条件性地添加样式:

<div class="hidden noscript:block">  <p>此体验需要 JavaScript 才能正常运行。请在浏览器设置中启用 JavaScript。</p></div>

打印样式

使用 print 变体来条件性地添加仅在文档打印时应用的样式:

<div>  <article class="print:hidden">    <h1>我的秘密披萨配方</h1>    <p>此配方是秘密,不得与任何人分享</p>    <!-- ... -->  </article>  <div class="hidden print:block">你真的想打印这个吗?这可是秘密!</div></div>

@supports 支持查询

使用 supports-[...] 变体可以根据用户浏览器是否支持特定功能来应用样式:

<div class="flex supports-[display:grid]:grid ...">  <!-- ... --></div>

在底层实现中,supports-[...] 变体会生成 @supports 规则,并接受方括号内任何可用于 @supports (...) 的内容,比如属性/值对,甚至是使用 andor 的表达式。

为了简洁起见,如果只需要检查属性是否支持(而不需要特定值),可以只指定属性名:

<div class="bg-black/75 supports-backdrop-filter:bg-black/25 supports-backdrop-filter:backdrop-blur ...">  <!-- ... --></div>

使用 not-supports-[...] 变体可以根据用户浏览器是否不支持特定功能来应用样式:

<div class="not-supports-[display:grid]:flex">  <!-- ... --></div>

你可以通过在 supports-* 命名空间中创建新变体来为项目中常用的 @supports 规则配置快捷方式:

@custom-variant supports-grid {  @supports (display: grid) {    @slot;  }}

然后就可以在项目中使用这些自定义的 supports-* 变体:

<div class="supports-grid:grid">  <!-- ... --></div>

@starting-style

使用 starting 变体可以设置元素首次渲染到 DOM 时,或从 display: none 过渡到可见状态时的外观:

<div>  <button popovertarget="my-popover">检查更新</button>  <div popover id="my-popover" class="opacity-0 starting:open:opacity-0 ...">    <!-- ... -->  </div></div>

属性选择器

ARIA 状态

使用 aria-* 变体可以根据 ARIA 属性有条件地设置样式。

例如,当 aria-checked 属性设置为 true 时应用 bg-sky-700 类,使用 aria-checked:bg-sky-700 类:

<div aria-checked="true" class="bg-gray-600 aria-checked:bg-sky-700">  <!-- ... --></div>

默认情况下,我们包含了最常见的布尔型 ARIA 属性的变体:

变体CSS
aria-busy&[aria-busy="true"]
aria-checked&[aria-checked="true"]
aria-disabled&[aria-disabled="true"]
aria-expanded&[aria-expanded="true"]
aria-hidden&[aria-hidden="true"]
aria-pressed&[aria-pressed="true"]
aria-readonly&[aria-readonly="true"]
aria-required&[aria-required="true"]
aria-selected&[aria-selected="true"]

你可以通过创建新变体来自定义可用的 aria-* 变体:

@custom-variant aria-asc (&[aria-sort="ascending"]);@custom-variant aria-desc (&[aria-sort="descending"]);

如果需要使用一次性 aria 变体(不适合包含在项目中),或者针对需要特定值的复杂 ARIA 属性,可以使用方括号动态生成属性:

发票编号客户金额
#100Pendant Publishing$2,000.00
#101Kruger Industrial Smoothing$545.00
#102J. Peterman$10,000.25
<table>  <thead>    <tr>      <th        aria-sort="ascending"        class="aria-[sort=ascending]:bg-[url('/img/down-arrow.svg')] aria-[sort=descending]:bg-[url('/img/up-arrow.svg')]"      >        发票编号      </th>      <!-- ... -->    </tr>  </thead>  <!-- ... --></table>

ARIA 状态变体也可以使用 group-aria-*peer-aria-* 变体来针对父元素和兄弟元素:

<table>  <thead>    <tr>    <th aria-sort="ascending" class="group">      发票编号      <svg class="group-aria-[sort=ascending]:rotate-0 group-aria-[sort=descending]:rotate-180"><!-- ... --></svg>    </th>    <!-- ... -->    </tr>  </thead>  <!-- ... --></table>

数据属性

使用 data-* 变体可以根据 数据属性 有条件地应用样式。

要检查数据属性是否存在(而非特定值),只需指定属性名称:

<!-- 会应用 --><div data-active class="border border-gray-300 data-active:border-purple-500">  <!-- ... --></div><!-- 不会应用 --><div class="border border-gray-300 data-active:border-purple-500">  <!-- ... --></div>

如果需要检查特定值,可以使用任意值:

<!-- 会应用 --><div data-size="large" class="data-[size=large]:p-8">  <!-- ... --></div><!-- 不会应用 --><div data-size="medium" class="data-[size=large]:p-8">  <!-- ... --></div>

或者,你可以通过在 data-* 命名空间中创建新变体,为项目中常用的数据属性配置快捷方式:

app.css
@import "tailwindcss";@custom-variant data-checked (&[data-ui~="checked"]);

然后就可以在项目中使用这些自定义的 data-* 变体:

<div data-ui="checked active" class="data-checked:underline">  <!-- ... --></div>

RTL 支持

在构建多方向布局时,使用 rtlltr 变体可以分别在从右到左和从左到右模式下有条件地添加样式:

从左到右

Tom Cook

运营总监

从右到左

تامر كرم

الرئيس التنفيذي

<div class="group flex items-center">  <img class="h-12 w-12 shrink-0 rounded-full" src="..." alt="" />  <div class="ltr:ml-3 rtl:mr-3">    <p class="text-gray-700 group-hover:text-gray-900 ...">...</p>    <p class="text-gray-500 group-hover:text-gray-700 ...">...</p>  </div></div>

请注意,这些变体仅在你需要构建同时支持从左到右和从右到左布局的网站时才有用。如果你构建的网站只需要支持单一方向,就不需要这些变体——只需应用适合你内容的样式即可。

展开/收起状态

使用 open 变体在 <details><dialog> 元素处于展开状态时条件性地添加样式:

尝试切换折叠面板查看样式变化

为什么叫 Ovaltine(阿华田)?

杯子是圆的,罐子也是圆的,应该叫 Roundtine(圆华田)才对。

<details class="border border-transparent open:border-black/10 open:bg-gray-100 ..." open>  <summary class="text-sm leading-6 font-semibold text-gray-900 select-none">为什么叫 Ovaltine(阿华田)?</summary>  <div class="mt-3 text-sm leading-6 text-gray-600">    <p>杯子是圆的,罐子也是圆的,应该叫 Roundtine(圆华田)才对。</p>  </div></details>

该变体也适用于弹出框的 :popover-open 伪类:

<div>  <button popovertarget="my-popover">打开弹出框</button>  <div popover id="my-popover" class="opacity-0 open:opacity-100 ...">    <!-- ... -->  </div></div>

为 inert 元素添加样式

inert 变体允许你为标记了 inert 属性的元素添加样式:

通知偏好设置

当有人发表评论时获取通知

当有人提到你时获取通知

<form>  <legend>通知偏好设置</legend>  <fieldset>    <input type="radio" />    <label> 自定义 </label>    <fieldset inert class="inert:opacity-50">      <!-- ... -->    </fieldset>    <input type="radio" />    <label> 全部 </label>  </fieldset></form>

这对于添加视觉提示非常有用,可以清晰地表明某些内容区域是不可交互的。

子选择器

直接子元素样式设置

虽然通常更推荐直接在子元素上应用工具类,但在你需要对那些无法直接控制的子元素设置样式时,可以使用 * 变体:

分类

销售
市场营销
SEO
分析
设计
策略
安全
增长
移动端
用户体验/界面
<div>  <h2>分类<h2>  <ul class="*:rounded-full *:border *:border-sky-100 *:bg-sky-50 *:px-2 *:py-0.5 dark:text-sky-300 dark:*:border-sky-500/15 dark:*:bg-sky-500/10 ...">    <li>销售</li>    <li>市场营销</li>    <li>SEO</li>    <!-- ... -->  </ul></div>

需要注意的是,由于生成的选择器具有特定性,直接在子元素上用工具类覆盖样式将不会生效:

不会生效,子元素无法覆盖自身的样式。

<ul class="*:bg-sky-50 ...">  <li class="bg-red-50 ...">销售</li>  <li>市场营销</li>  <li>SEO</li>  <!-- ... --></ul>

为所有后代元素设置样式

* 类似,** 变体可用于为元素的子元素设置样式。主要区别在于 ** 会将样式应用于 所有 后代元素,而不仅仅是直接子元素。当你将其与另一个变体结合使用时,这对于缩小选择范围特别有用:

<ul class="**:data-avatar:size-12 **:data-avatar:rounded-full ...">  {#each items as item}    <li>      <img src={item.src} data-avatar />      <p>{item.name}</p>    </li>  {/each}</ul>

自定义变体

使用任意变体

就像任意值允许你在工具类中使用自定义值一样,任意变体允许你直接在 HTML 中编写自定义选择器变体。

任意变体是用方括号包裹的表示选择器的格式字符串。例如,这个任意变体会在元素具有 is-dragging 类时将光标变为 grabbing

<ul role="list">  {#each items as item}    <li class="[&.is-dragging]:cursor-grabbing">{item}</li>  {/each}</ul>

任意变体可以与内置变体或其他任意变体组合使用,就像 Tailwind 中的其他变体一样:

<ul role="list">  {#each items as item}    <li class="[&.is-dragging]:active:cursor-grabbing">{item}</li>  {/each}</ul>

如果选择器中需要空格,可以使用下划线代替。例如,这个任意变体会选择添加了该类的元素内所有的 p 元素:

<div class="[&_p]:mt-4">  <p>Lorem ipsum...</p>  <ul>    <li>      <p>Lorem ipsum...</p>    </li>    <!-- ... -->  </ul></div>

你也可以在任意变体中使用 @media@supports 等 at-规则:

<div class="flex [@supports(display:grid)]:grid">  <!-- ... --></div>

使用 at-规则自定义变体时,不需要 & 占位符,就像使用预处理器嵌套时一样。

注册自定义变体

如果你发现自己在项目中多次使用相同的任意变体,可以考虑使用 @custom-variant 指令创建一个自定义变体:

@custom-variant theme-midnight (&:where([data-theme="midnight"] *));

现在你可以在 HTML 中使用 theme-midnight:<utility> 变体:

<html data-theme="midnight">  <button class="theme-midnight:bg-black ..."></button></html>

了解更多关于添加自定义变体的信息,请参阅添加自定义变体文档

附录

快速参考

Tailwind 默认包含的所有变体(variant)的快速参考表。

VariantCSS
hover@media (hover: hover) { &:hover }
focus&:focus
focus-within&:focus-within
focus-visible&:focus-visible
active&:active
visited&:visited
target&:target
*:is(& > *)
**:is(& *)
has-[...]&:has(...)
group-[...]&:is(:where(.group)... *)
peer-[...]&:is(:where(.peer)... ~ *)
in-[...]:where(...) &
not-[...]&:not(...)
inert&:is([inert], [inert] *)
first&:first-child
last&:last-child
only&:only-child
odd&:nth-child(odd)
even&:nth-child(even)
first-of-type&:first-of-type
last-of-type&:last-of-type
only-of-type&:only-of-type
nth-[...]&:nth-child(...)
nth-last-[...]&:nth-last-child(...)
nth-of-type-[...]&:nth-of-type(...)
nth-last-of-type-[...]&:nth-last-of-type(...)
empty&:empty
disabled&:disabled
enabled&:enabled
checked&:checked
indeterminate&:indeterminate
default&:default
optional&:optional
required&:required
valid&:valid
invalid&:invalid
user-valid&:user-valid
user-invalid&:user-invalid
in-range&:in-range
out-of-range&:out-of-range
placeholder-shown&:placeholder-shown
details-content&:details-content
autofill&:autofill
read-only&:read-only
before&::before
after&::after
first-letter&::first-letter
first-line&::first-line
marker&::marker, & *::marker
selection&::selection
file&::file-selector-button
backdrop&::backdrop
placeholder&::placeholder
sm@media (width >= 40rem)
md@media (width >= 48rem)
lg@media (width >= 64rem)
xl@media (width >= 80rem)
2xl@media (width >= 96rem)
min-[...]@media (width >= ...)
max-sm@media (width < 40rem)
max-md@media (width < 48rem)
max-lg@media (width < 64rem)
max-xl@media (width < 80rem)
max-2xl@media (width < 96rem)
max-[...]@media (width < ...)
@3xs@container (width >= 16rem)
@2xs@container (width >= 18rem)
@xs@container (width >= 20rem)
@sm@container (width >= 24rem)
@md@container (width >= 28rem)
@lg@container (width >= 32rem)
@xl@container (width >= 36rem)
@2xl@container (width >= 42rem)
@3xl@container (width >= 48rem)
@4xl@container (width >= 56rem)
@5xl@container (width >= 64rem)
@6xl@container (width >= 72rem)
@7xl@container (width >= 80rem)
@min-[...]@container (width >= ...)
@max-3xs@container (width < 16rem)
@max-2xs@container (width < 18rem)
@max-xs@container (width < 20rem)
@max-sm@container (width < 24rem)
@max-md@container (width < 28rem)
@max-lg@container (width < 32rem)
@max-xl@container (width < 36rem)
@max-2xl@container (width < 42rem)
@max-3xl@container (width < 48rem)
@max-4xl@container (width < 56rem)
@max-5xl@container (width < 64rem)
@max-6xl@container (width < 72rem)
@max-7xl@container (width < 80rem)
@max-[...]@container (width < ...)
dark@media (prefers-color-scheme: dark)
motion-safe@media (prefers-reduced-motion: no-preference)
motion-reduce@media (prefers-reduced-motion: reduce)
contrast-more@media (prefers-contrast: more)
contrast-less@media (prefers-contrast: less)
forced-colors@media (forced-colors: active)
inverted-colors@media (inverted-colors: inverted)
pointer-fine@media (pointer: fine)
pointer-coarse@media (pointer: coarse)
pointer-none@media (pointer: none)
any-pointer-fine@media (any-pointer: fine)
any-pointer-coarse@media (any-pointer: coarse)
any-pointer-none@media (any-pointer: none)
portrait@media (orientation: portrait)
landscape@media (orientation: landscape)
noscript@media (scripting: none)
print@media print
supports-[]@supports ()
aria-busy&[aria-busy="true"]
aria-checked&[aria-checked="true"]
aria-disabled&[aria-disabled="true"]
aria-expanded&[aria-expanded="true"]
aria-hidden&[aria-hidden="true"]
aria-pressed&[aria-pressed="true"]
aria-readonly&[aria-readonly="true"]
aria-required&[aria-required="true"]
aria-selected&[aria-selected="true"]
aria-[]&[aria-]
data-[]&[data-]
rtl&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *)
ltr&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *)
open&:is([open], :popover-open, :open)
starting@starting-style

伪类参考

这是 Tailwind 中包含的所有伪类变体的完整示例列表,作为本指南开头伪类文档的补充。

:hover

使用 hover 变体在用户鼠标悬停时设置元素样式:

<div class="bg-black hover:bg-white ...">  <!-- ... --></div>

:focus

使用 focus 变体在元素获得焦点时设置样式:

<input class="border-gray-300 focus:border-blue-400 ..." />

:focus-within

使用 focus-within 变体在元素或其任意子元素获得焦点时设置样式:

<div class="focus-within:shadow-lg ...">  <input type="text" /></div>

:focus-visible

使用 focus-visible 变体在元素通过键盘获得焦点时设置样式:

<button class="focus-visible:outline-2 ...">提交</button>

:active

使用 active 变体在元素被按下时设置样式:

<button class="bg-blue-500 active:bg-blue-600 ...">提交</button>

:visited

使用 visited 变体在链接已被访问过时设置样式:

<a href="https://seinfeldquotes.com" class="text-blue-600 visited:text-purple-600 ..."> 灵感 </a>

:target

使用 target 变体在元素的 ID 匹配当前 URL 片段时设置样式:

<div id="about" class="target:shadow-lg ...">  <!-- ... --></div>

:first-child

使用 first 变体来设置第一个子元素的样式:

<ul>  {#each people as person}    <li class="py-4 first:pt-0 ...">      <!-- ... -->    </li>  {/each}</ul>

:last-child

使用 last 变体来设置最后一个子元素的样式:

<ul>  {#each people as person}    <li class="py-4 last:pb-0 ...">      <!-- ... -->    </li>  {/each}</ul>

:only-child

使用 only 变体来设置唯一子元素的样式:

<ul>  {#each people as person}    <li class="py-4 only:py-0 ...">      <!-- ... -->    </li>  {/each}</ul>

:nth-child(odd)

使用 odd 变体来设置奇数位子元素的样式:

<table>  {#each people as person}    <tr class="bg-white odd:bg-gray-100 ...">      <!-- ... -->    </tr>  {/each}</table>

:nth-child(even)

使用 even 变体来设置偶数位子元素的样式:

<table>  {#each people as person}    <tr class="bg-white even:bg-gray-100 ...">      <!-- ... -->    </tr>  {/each}</table>

:first-of-type

使用 first-of-type 变体来设置同类型第一个子元素的样式:

<nav>  <img src="/logo.svg" alt="Vandelay Industries" />  {#each links as link}    <a href="#" class="ml-2 first-of-type:ml-6 ...">      <!-- ... -->    </a>  {/each}</nav>

:last-of-type

使用 last-of-type 变体来样式化某个类型的最后一个子元素:

<nav>  <img src="/logo.svg" alt="Vandelay Industries" />  {#each links as link}    <a href="#" class="mr-2 last-of-type:mr-6 ...">      <!-- ... -->    </a>  {/each}  <button>More</button></nav>

:only-of-type

使用 only-of-type 变体来样式化某个类型的唯一子元素:

<nav>  <img src="/logo.svg" alt="Vandelay Industries" />  {#each links as link}    <a href="#" class="mx-2 only-of-type:mx-6 ...">      <!-- ... -->    </a>  {/each}  <button>More</button></nav>

:nth-child()

使用 nth 变体来样式化特定位置的元素:

<nav>  <img src="/logo.svg" alt="Vandelay Industries" />  {#each links as link}    <a href="#" class="mx-2 nth-3:mx-6 nth-[3n+1]:mx-7 ...">      <!-- ... -->    </a>  {/each}  <button>More</button></nav>

:nth-last-child()

使用 nth-last 变体来样式化从末尾计数的特定位置元素:

<nav>  <img src="/logo.svg" alt="Vandelay Industries" />  {#each links as link}    <a href="#" class="mx-2 nth-last-3:mx-6 nth-last-[3n+1]:mx-7 ...">      <!-- ... -->    </a>  {/each}  <button>More</button></nav>

:nth-of-type()

使用 nth-of-type 变体来样式化同类型元素中的特定位置元素:

<nav>  <img src="/logo.svg" alt="Vandelay Industries" />  {#each links as link}    <a href="#" class="mx-2 nth-of-type-3:mx-6 nth-of-type-[3n+1]:mx-7 ...">      <!-- ... -->    </a>  {/each}  <button>More</button></nav>

:nth-last-of-type()

使用 nth-last-of-type 变体从末尾开始对同类型元素的特定位置进行样式设置:

<nav>  <img src="/logo.svg" alt="Vandelay 工业公司" />  {#each links as link}    <a href="#" class="mx-2 nth-last-of-type-3:mx-6 nth-last-of-type-[3n+1]:mx-7 ...">      <!-- ... -->    </a>  {/each}  <button>更多</button></nav>

:empty

使用 empty 变体对没有内容的元素进行样式设置:

<ul>  {#each people as person}    <li class="empty:hidden ...">{person.hobby}</li>  {/each}</ul>

:disabled

使用 disabled 变体对禁用的输入框进行样式设置:

<input class="disabled:opacity-75 ..." />

:enabled

使用 enabled 变体对启用的输入框进行样式设置,当您只想在元素未禁用时应用其他样式时特别有用:

<input class="enabled:hover:border-gray-400 disabled:opacity-75 ..." />

:checked

使用 checked 变体对选中的复选框或单选按钮进行样式设置:

<input type="checkbox" class="appearance-none checked:bg-blue-500 ..." />

:indeterminate

使用 indeterminate 变体对处于不确定状态的复选框或单选按钮进行样式设置:

<input type="checkbox" class="appearance-none indeterminate:bg-gray-300 ..." />

:default

使用 default 变体对页面初始加载时的默认选项、复选框或单选按钮进行样式设置:

<input type="checkbox" class="default:outline-2 ..." />

:optional

使用 optional 变体为可选输入框设置样式:

<input class="border optional:border-red-500 ..." />

:required

使用 required 变体为必填输入框设置样式:

<input required class="border required:border-red-500 ..." />

:valid

使用 valid 变体为有效输入框设置样式:

<input required class="border valid:border-green-500 ..." />

:invalid

使用 invalid 变体为无效输入框设置样式:

<input required class="border invalid:border-red-500 ..." />

:user-valid

使用 user-valid 变体为有效且用户已交互过的输入框设置样式:

<input required class="border user-valid:border-green-500" />

:user-invalid

使用 user-invalid 变体为无效且用户已交互过的输入框设置样式:

<input required class="border user-invalid:border-red-500" />

:in-range

使用 in-range 变体为值在指定范围内的输入框设置样式:

<input min="1" max="5" class="in-range:border-green-500 ..." />

:out-of-range

使用 out-of-range 变体为值超出指定范围的输入框设置样式:

<input min="1" max="5" class="out-of-range:border-red-500 ..." />

:placeholder-shown

当占位符显示时,使用 placeholder-shown 变体来设置输入框的样式:

<input class="placeholder-shown:border-gray-500 ..." placeholder="you@example.com" />

:details-content

使用 details-content 变体来设置 <details> 元素内容的样式:

<details class="details-content:bg-gray-100 ...">  <summary>Details</summary>  This is a secret.</details>

:autofill

当输入框被浏览器自动填充时,使用 autofill 变体来设置其样式:

<input class="autofill:bg-yellow-200 ..." />

:read-only

当输入框为只读状态时,使用 read-only 变体来设置其样式:

<input class="read-only:bg-gray-100 ..." />
Copyright © 2025 Tailwind Labs Inc.·Trademark Policy