1. Core concepts
  2. Hover, focus, and other states

Core concepts

悬停、焦点和其他状态

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

Tailwind 中的每个工具类都可以通过在类名前加一个描述目标条件的变体来有条件地应用。

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

将鼠标悬停在此按钮上可以看到背景色的变化

<button class="bg-sky-500 hover:bg-sky-700 ...">Save changes</button>
How does this compare to traditional 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 变体来设置作为第一个或最后一个子元素时的样式:

<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 变体来设置作为奇数或偶数子元素时的样式:

NameTitleEmail
Jane CooperRegional Paradigm Technician[email protected]
Cody FisherProduct Directives Officer[email protected]
Leonard KrasnerSenior Designer[email protected]
Emily SelmanVP, Hardware Engineering[email protected]
Anna RobertsChief Strategy Officer[email protected]
<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-* 变体根据元素的后代状态或内容设置样式:

Payment method
<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-* 变体来设置目标元素的样式:

Today
<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>  </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

重要的是要注意,peer 标记只能用于前面的同级元素,因为后续同级选择器在 CSS 中的工作方式:

不起作用,只有前面的同级元素可以标记为同级

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

区分同级元素

当使用多个同级元素时,你可以通过给同级元素一个唯一的名称来基于特定同级元素的状态设置样式,使用 peer/{name} 类,并在变体中包含该名称,如 peer-checked/{name}

Published status
<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="[email protected]" /></label>

使用这些变体时,Tailwind 会自动添加 content: '' 作为默认值,因此你不必指定它,除非你想要一个不同的值:

When you look annoyed all the time, people think that you're busy.
<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 变体来设置任何输入或文本区域的占位符文本样式:

<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 变体来设置列表中的计数器或项目符号样式:

Ingredients

  • 5 cups chopped Porcini mushrooms
  • 1/2 cup of olive oil
  • 3lb of celery
<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 变体来设置活动文本选择的样式:

尝试用鼠标选择一些文本

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 was a marine biologist.

<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 变体来设置第一字母样式:

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 变体来提供暗色模式的覆盖:

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-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` 以查看变化

We need this to steal your identity.

<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` 以查看变化

Choose a theme:
<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 还包括一个强制颜色调整工具类,以选择加入和退出强制颜色。

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>

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 属性的变体:

VariantCSS
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 属性,请使用方括号生成一个任意值的属性:

Invoice #ClientAmount
#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-* 变体根据数据属性有条件地应用样式。

要检查数据属性是否存在(而不是特定值),你可以只指定属性名称:

<!-- 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-* 命名空间中创建一个新变体来配置项目中常用的数据属性的快捷方式:

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

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

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

RTL 支持

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

Left-to-right

Tom Cook

Director of Operations

Right-to-left

تامر كرم

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

<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> 元素处于打开状态时有条件地添加样式:

尝试切换详细信息以查看样式变化

Why do they call it Ovaltine?

The mug is round. The jar is round. They should call it 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-open 伪类:

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

设置不可交互元素的样式

inert 变体允许你设置标记为 inert 属性的元素的样式:

Notification preferences

Get notified when someones posts a comment on a post.

Get notified when someones mentions you.

<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>

这对于添加视觉提示以明确内容部分不可交互非常有用。

子选择器

设置直接子元素的样式

虽然通常将工具类直接放在子元素上更好,但在你无法控制的情况下,你可以使用 * 变体来设置直接子元素的样式:

Categories

Sales
Marketing
SEO
Analytics
Design
Strategy
Security
Growth
Mobile
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>

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

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

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

注册自定义变体

如果你发现自己在项目中多次使用相同的任意变体,可能值得创建一个自定义变体:

@custom-variant pointer-coarse {  @media (pointer: coarse) {    @slot;  }}

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

<button class="pointer-coarse:size-12 ..."></button>

当不需要嵌套时,可以使用简写语法创建变体:

@custom-variant pointer-coarse (@media (pointer: coarse));

当自定义变体有多个规则时,它们可以相互嵌套:

@custom-variant any-hover {  @media (any-hover: hover) {    &:hover {      @slot;    }  }}

附录

快速参考

这是一个包含 Tailwind 默认包含的每个变体的快速参考表。

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
in-range&:in-range
out-of-range&:out-of-range
placeholder-shown&:placeholder-shown
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)
portrait@media (orientation: portrait)
landscape@media (orientation: landscape)
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)
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[dir="rtl"] &
ltr[dir="ltr"] &
open&:is([open], :popover-open)
forced-colors@media (forced-colors: active)
starting@starting-style

伪类参考

这是一个包含所有伪类变体示例的综合列表,以补充本指南开头的伪类文档

: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

使用 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 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

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

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

:optional

使用 optional 变体在输入是可选时设置样式:

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

:required

使用 required 变体在输入是必填时设置样式:

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

:valid

使用 valid 变体在输入有效时设置样式:

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

:invalid

使用 invalid 变体在输入无效时设置样式:

<input class="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="[email protected]" />

:autofill

使用 autofill 变体在输入已被浏览器自动填充时设置样式:

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

:read-only

使用 read-only 变体在输入为只读时设置样式:

<input class="read-only:bg-gray-100 ..." />
版权所有 © 2025 Tailwind Labs Inc.·商标政策