1. 核心概念
  2. 悬停、焦点和其他状态

核心概念

悬停、焦点和其他状态

使用实用程序在悬停、焦点等状态下设置元素样式。

Tailwind 中的每个实用程序类都可以通过在类名称的开头添加一个变体来有条件地应用,该变体描述了您要定位的条件。

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

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

<button class="bg-sky-500 hover:bg-sky-700 ...">Save changes</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 ...">Save changes</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 ...">
Save changes
</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}
<!-- Remove top/bottom padding when first/last child -->
<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}
<!-- Use different background colors for odd and even rows -->
<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

产品设计师,就职于 planeteria.tech

Casey Jordan

很高兴来到这里。

Alex Reed

一位跨学科设计师,工作于艺术与技术的交叉领域。

alex-reed.com

Taylor Bailey

推动像素。投掷 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 />
Create a to do list
</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 ...">New project</h3>
</div>
<p class="text-gray-500 group-hover:text-white ...">Create a new project from a variety of starting templates.</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 ...">Call</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">
Published
</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="...">Email</span>
<input type="email" class="peer ..." />
<p class="invisible peer-invalid:visible ...">Please provide a valid email address.</p>
</label>
</form>

这使得实现各种巧妙的技巧成为可能,例如浮动标签,而无需任何 JS。

此模式适用于每个伪类变体,例如 peer-focuspeer-requiredpeer-disabled

重要的是要注意,由于 CSS 中后续兄弟选择器的工作方式,peer 标记只能用于之前的兄弟元素

将不起作用,只有之前的兄弟元素可以标记为同级元素

<label>
<span class="peer-invalid:text-red-500 ...">Email</span>
<input type="email" class="peer ..." />
</label>

区分同级元素

当使用多个同级元素时,您可以通过使用 peer/{name} 类为该同级元素指定唯一的名称,并使用诸如 peer-checked/{name} 之类的类将该名称包含在变体中,从而根据特定同级元素的状态设置某些内容的样式

发布状态
<fieldset>
<legend>Published status</legend>
<input id="draft" class="peer/draft" type="radio" name="status" checked />
<label for="draft" class="peer-checked/draft:text-sky-500">Draft</label>
<input id="published" class="peer/published" type="radio" name="status" />
<label for="published" class="peer-checked/published:text-sky-500">Published</label>
<div class="hidden peer-checked/draft:block">Drafts are only visible to administrators.</div>
<div class="hidden peer-checked/published:block">Your post will be publicly visible on your site.</div>
</fieldset>

同级元素可以随意命名,无需以任何方式配置 — 只需在标记中直接命名您的同级元素,Tailwind 就会自动生成必要的 CSS。

任意同级元素

您可以通过在方括号之间提供您自己的选择器作为任意值来动态创建一次性 peer-* 变体

<form>
<label for="email">Email:</label>
<input id="email" name="email" type="email" class="is-dirty peer" required />
<div class="peer-[.is-dirty]:peer-required:block hidden">This field is required.</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-['*'] ...">Email</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">
When you look
<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">annoyed</span>
</span>
all the time, people think that you're busy.
</blockquote>

值得注意的是,在 Tailwind 项目中,您实际上不需要 ::before::after 伪元素来完成大多数事情 — 通常只需使用真实的 HTML 元素即可。

例如,这是上面相同的设计,但使用 <span> 而不是 ::before 伪元素,这更容易阅读,而且实际上代码更少

<blockquote class="text-center text-2xl font-semibold text-gray-900 italic">
When you look
<span class="relative">
<span class="absolute -inset-1 block -skew-y-3 bg-pink-500" aria-hidden="true"></span>
<span class="relative text-white">annoyed</span>
</span>
all the time, people think that you're busy.
</blockquote>

beforeafter 保留给伪元素的内容实际上不在 DOM 中且无法被用户选择的重要情况。

::placeholder

使用 placeholder 变体设置任何输入或 textarea 的占位符文本的样式

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

::file

使用 file 变体设置文件输入中按钮的样式

Current profile photo
<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>
So I started to walk into the water. I won't lie to you boys, I was terrified. But I pressed on, and as I made my
way past the breakers a strange calm came over me. I don't know if it was divine intervention or the kinship of all
living things but I tell you Jerry at that moment, I <em>was</em> a marine biologist.
</p>
</div>

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

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

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

::first-line 和 ::first-letter

使用 first-line 变体设置内容块中第一行的样式,并使用 first-letter 变体设置第一个字母的样式

好吧,让我告诉你一些事情,有趣的家伙。你知道那个小邮戳,上面写着“纽约公共图书馆”吗?好吧,这对你来说可能没有任何意义,但这对我很重要。非常重要。

当然,如果你愿意就笑吧。我以前见过你这种类型的人:花哨,出风头,炫耀习俗。是的,我知道你在想什么。这家伙为什么对旧图书馆的书籍如此大惊小怪?好吧,让我给你一个提示,年轻人。

<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 ...">Writes upside-down</h3>
<p class="text-gray-500 dark:text-gray-400 ...">
The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.
</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>
Processing...
</button>

Tailwind 还包括一个 motion-safe 变体,该变体仅在用户请求减少运动时添加样式。当使用 motion-reduce 辅助工具意味着必须“撤消”许多样式时,这可能很有用

<!-- Using `motion-reduce` can mean lots of "undoing" styles -->
<button class="transition hover:-translate-y-0.5 motion-reduce:transition-none motion-reduce:hover:translate-y-0 ...">
Save changes
</button>
<!-- Using `motion-safe` is less code in these situations -->
<button class="motion-safe:transition motion-safe:hover:-translate-x-0.5 ...">Save changes</button>

prefers-contrast

prefers-contrast 媒体查询告诉您用户是否请求更多或更少的对比度。

当用户请求更高对比度时,使用 contrast-more 变体有条件地添加样式

尝试在您的开发者工具中模拟“prefers-contrast: more”以查看更改

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

<label class="block">
<span class="block text-sm font-medium text-gray-700">Social Security Number</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 ...">We need this to steal your identity.</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">Cyan</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 还包括强制颜色调整实用程序,用于选择加入和退出强制颜色。

inverted-colors

当用户启用反转颜色方案时,使用 inverted-colors 变体有条件地添加样式

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

pointer 和 any-pointer

pointer 媒体查询告诉您用户是否拥有主要指点设备(如鼠标)以及该指点设备的精度。

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

尝试在您的开发者工具中模拟触摸设备以查看更改

<fieldset aria-label="Choose a memory option">
<div class="flex items-center justify-between">
<div>RAM</div>
<a href="#"> See performance specs </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 来定位缺少指点设备的情况。

orientation

当视口处于特定方向时,使用 portraitlandscape 变体有条件地添加样式

<div>
<div class="portrait:hidden">
<!-- ... -->
</div>
<div class="landscape:hidden">
<p>This experience is designed to be viewed in landscape. Please rotate your device to view the site.</p>
</div>
</div>

scripting

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

<div class="hidden noscript:block">
<p>This experience requires JavaScript to function. Please enable JavaScript in your browser settings.</p>
</div>

print

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

<div>
<article class="print:hidden">
<h1>My Secret Pizza Recipe</h1>
<p>This recipe is a secret, and must not be shared with anyone</p>
<!-- ... -->
</article>
<div class="hidden print:block">Are you seriously trying to print this? It's secret!</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">Check for updates</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')]"
>
Invoice #
</th>
<!-- ... -->
</tr>
</thead>
<!-- ... -->
</table>

ARIA 状态变体还可以使用 group-aria-*peer-aria-* 变体来定位父元素和兄弟元素

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

Data attributes

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

要检查 data 属性是否存在(而不是特定值),您只需指定属性名称

<!-- Will apply -->
<div data-active class="border border-gray-300 data-active:border-purple-500">
<!-- ... -->
</div>
<!-- Will not apply -->
<div class="border border-gray-300 data-active:border-purple-500">
<!-- ... -->
</div>

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

<!-- Will apply -->
<div data-size="large" class="data-[size=large]:p-8">
<!-- ... -->
</div>
<!-- Will not apply -->
<div data-size="medium" class="data-[size=large]:p-8">
<!-- ... -->
</div>

或者,您可以通过在 data-* 命名空间中创建新变体,为您项目中常用的 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>

请记住,这些变体仅在您构建需要支持从左到右从右到左布局的站点时才有用。如果您构建的站点只需要支持单个方向,则不需要这些变体 — 只需应用对您的内容有意义的样式即可。

打开/关闭状态

<details><dialog> 元素处于打开状态时,使用 open 变体有条件地添加样式

尝试切换 disclosure 以查看样式变化

他们为什么叫它 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">Why do they call it Ovaltine?</summary>
<div class="mt-3 text-sm leading-6 text-gray-600">
<p>The mug is round. The jar is round. They should call it Roundtine.</p>
</div>
</details>

此变体还针对 popover 的 :popover-open 伪类

<div>
<button popovertarget="my-popover">Open Popover</button>
<div popover id="my-popover" class="opacity-0 open:opacity-100 ...">
<!-- ... -->
</div>
</div>

样式化 inert 元素

inert 变体允许您样式化标记有 inert 属性的元素

通知偏好设置

当有人在帖子下发布评论时收到通知。

当有人提及您时收到通知。

<form>
<legend>Notification preferences</legend>
<fieldset>
<input type="radio" />
<label> Custom </label>
<fieldset inert class="inert:opacity-50">
<!-- ... -->
</fieldset>
<input type="radio" />
<label> Everything </label>
</fieldset>
</form>

这对于添加视觉提示非常有用,这些提示可以清楚地表明内容部分不是交互式的。

子选择器

样式化直接子元素

虽然通常最好将实用程序类直接放在子元素上,但在您需要样式化您无法控制的直接子元素的情况下,可以使用 * 变体

类别

销售
营销
SEO
分析
设计
策略
安全
增长
移动
UX/UI
<div>
<h2>Categories<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>Sales</li>
<li>Marketing</li>
<li>SEO</li>
<!-- ... -->
</ul>
</div>

重要的是要注意,由于生成的子选择器的特殊性,直接在子元素本身上使用实用程序覆盖样式将不起作用

不起作用,子元素无法覆盖自己的样式。

<ul class="*:bg-sky-50 ...">
<li class="bg-red-50 ...">Sales</li>
<li>Marketing</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>

您还可以在任意变体中使用 at-rules,如 @media@supports

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

使用 at-rule 自定义变体时,& 占位符不是必需的,就像使用预处理器进行嵌套时一样。

注册自定义变体

如果您发现自己在项目中多次使用相同的任意变体,则可能值得使用 @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 默认包含的每个变体的快速参考表。

变体CSS
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 ...">Submit</button>

:active

当元素被按下时,使用 active 变体来设置元素样式

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

:visited

当链接已被访问时,使用 visited 变体来设置链接样式

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

:target

如果元素的 ID 与当前 URL 片段匹配,则使用 target 变体来设置元素样式

<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 Industries" />
{#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>More</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

当页面初始加载时,如果 option、复选框或单选按钮是默认值,则使用 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 显示时,使用 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 ..." />
版权所有 © 2025 Tailwind Labs Inc.·商标政策