Skip to content

处理 Hover,Focus, and Other States

使用实用程序来为元素设置悬停、焦点等样式。

Tailwind 中的每个实用类都可以通过在类名的开头添加一个描述你想要定位的条件的修饰符来进行条件应用。

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

👆 将鼠标悬停在此按钮上,即可看到背景颜色发生变化

html
<button class="bg-sky-500 hover:bg-sky-700 ...">
  Save changes
</button>
这与传统的 CSS 相比如何?

在传统的方式下编写 CSS 时,一个类名会根据当前状态执行不同的操作。

✘ 传统上,同一类名称在悬停时应用不同的样式

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

在Tailwind中,你不是将悬停状态的样式添加到现有的类中,而是将另一个类添加到元素上,该类只在悬停时执行某些操作。

✓ 在Tailwind中,使用单独的类来表示默认状态和悬停状态

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

注意 hover:bg-sky-700 只定义了 :hover 状态的样式?它默认情况下不起作用,但一旦你将鼠标悬停在具有该类的元素上,背景颜色就会改变为 sky-700

这就是我们所说的实用类可以有条件地应用的意思——通过使用修饰符,您可以精确控制设计在不同状态下的行为,而无需离开您的HTML。🎉 💯

Tailwind 包括几乎你所需的所有修改器,包括:

  • 伪类,如::hover:focus:first-child:required
  • 伪元素,如:::before::after::placeholder::selection
  • 媒体和特征查询,如响应式断点、暗黑模式和 prefers-reduced-motion
  • 属性选择器,如 [dir="rtl"][open]

这些修饰符甚至可以叠加,以针对更具体的情况,例如在暗模式下,在中等断点上悬停时更改背景颜色:

html
<button class="dark:md:hover:bg-fuchsia-600 ...">
  Save changes
</button>

在本指南中,您将了解框架中的每个修饰符,如何将它们与您自己的自定义类一起使用,甚至如何创建您自己的修饰符。

伪类

Hover、Focus 和 active

在悬停、焦点和激活状态下使用 hoverfocusactive 修饰符的样式元素:

👆 尝试与此按钮进行交互,以查看悬停、焦点和激活状态

html
<button class="bg-violet-500 hover:bg-violet-600 active:bg-violet-700 focus:outline-none focus:ring focus:ring-violet-300 ...">
  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

html
<ul role="list" class="p-6 divide-y divide-slate-200">
  {#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-slate-900">{person.name}</p>
        <p class="text-sm text-slate-500 truncate">{person.email}</p>
      </div>
    </li>
  {/each}
</ul>

您还可以使用 oddeven 修饰符来为元素设置奇数或偶数子元素的样式:

Name Title Email
Jane Cooper Regional Paradigm Technician jane.cooper@example.com
Cody Fisher Product Directives Officer cody.fisher@example.com
Leonard Krasner Senior Designer leonard.krasner@example.com
Emily Selman VP, Hardware Engineering emily.selman@example.com
Anna Roberts Chief Strategy Officer anna.roberts@example.com
html
<table>
  <!-- ... -->
  <tbody>
    {#each people as person}
      <!-- Use a white background for odd rows, and slate-50 for even rows -->
      <tr class="odd:bg-white even:bg-slate-50">
        <td>{person.name}</td>
        <td>{person.title}</td>
        <td>{person.email}</td>
      </tr>
    {/each}
  </tbody>
</table>

Tailwind 还包括用于其他结构伪类的修饰符,比如 :only-child:first-of-type:empty 等等。

请参阅伪类引用以获取可用伪类修饰符的完整列表。

表单状态

使用 requiredinvaliddisabled 等修饰符来设置不同状态下的样式表单元素:

👆 尝试使电子邮件地址有效,以查看样式更改

html
<form>
  <label class="block">
    <span class="block text-sm font-medium text-slate-700">Username</span>
    <!-- Using form state modifiers, the classes can be identical for every input -->
    <input type="text" value="tbone" disabled class="mt-1 block w-full px-3 py-2 bg-white border border-solid border-slate-300 rounded-md text-sm shadow-sm placeholder-slate-400
      focus:outline-none focus:border-sky-500 focus:ring-1 focus:ring-sky-500
      disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none
      invalid:border-pink-500 invalid:text-pink-600
      focus:invalid:border-pink-500 focus:invalid:ring-pink-500
    "/>
  </label>
  <!-- ... -->
</form>

使用修饰符可以减少模板中的条件逻辑数量,让您可以使用相同的类集合,而不管输入处于什么状态,并让浏览器为您应用正确的样式。

Tailwind 还包括用于其他表单状态的修饰符,如 :read-only:indeterminate:checked 等等。

请参阅伪类引用以获取可用伪类修饰符的完整列表。

基于父级状态的样式(group-{modifier})

当您需要根据某个父元素的状态来设置元素样式时,请使用 group 类标记父元素,并使用 group-* 修饰符(如 group-hover )来设置目标元素的样式:

👆 将鼠标悬停在卡片上,可以看到两个文本元素的颜色都会改变

html
<a href="#" class="group block max-w-xs mx-auto rounded-lg p-6 bg-white ring-1 ring-slate-900/5 shadow-lg space-y-3 hover:bg-sky-500 hover:ring-sky-500">
  <div class="flex items-center space-x-3">
    <svg class="h-6 w-6 stroke-sky-500 group-hover:stroke-white" fill="none" viewBox="0 0 24 24"><!-- ... --></svg>
    <h3 class="text-slate-900 group-hover:text-white text-sm font-semibold">New project</h3>
  </div>
  <p class="text-slate-500 group-hover:text-white text-sm">Create a new project from a variety of starting templates.</p>
</a>

这种模式适用于每个伪类修饰符,例如 group-focusgroup-active ,甚至 group-odd

区分嵌套的群组

在嵌套组时,您可以通过为父组件赋予一个唯一的组名(使用 group/{name} 类),并在修改器中包含该名称(使用类似 group-hover/{name} 的类)来基于特定父组件的状态设置样式。

html
<ul role="list">
  {#each people as person}
    <li class="group/item hover:bg-slate-100 ...">
      <img src="{person.imageUrl}" alt="" />
      <div>
        <a href="{person.url}">{person.name}</a>
        <p>{person.title}</p>
      </div>
      <a class="group/edit invisible hover:bg-slate-200 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-slate-500 ...">
          <!-- ... -->
        </svg>
      </a>
    </li>
  {/each}
</ul>

组可以按您喜欢的方式命名,无需进行任何配置 - 只需在标记中直接命名您的组,Tailwind 将自动生成必要的 CSS。

任意分组

您可以通过在方括号中提供自己的选择器作为任意值,即时创建一次性的修饰符。

html
<div class="group is-published">
  <div class="hidden group-[.is-published]:block">
    Published
  </div>
</div>
css
.group.is-published .group-\[\.is-published\]\:block {
  display: block;
}

为了更好地控制,您可以使用 & 字符来标记 .group 在最终选择器中相对于您传入的选择器应该出现的位置:

html
<div class="group">
  <div class="group-[:nth-of-type(3)_&]:block">
    <!-- ... -->
  </div>
</div>
css
:nth-of-type(3) .group .group-\[\:nth-of-type\(3\)_\&\]\:block {
  display: block;
}

基于同级状态的样式(peer-{modifier})

当您需要根据兄弟元素的状态来设置元素样式时,请使用 peer 类标记兄弟元素,并使用 peer-* 修饰符,如 peer-invalid 来设置目标元素的样式:

👆 尝试使电子邮件地址有效,以消除警告

html
<form>
  <label class="block">
    <span class="block text-sm font-medium text-slate-700">Email</span>
    <input type="email" class="peer ..."/>
    <p class="mt-2 invisible peer-invalid:visible text-pink-600 text-sm">
      请提供有效的电子邮件地址。
    </p>
  </label>
</form>

这使得可以做各种花哨的技巧,比如浮动标签,而无需任何 JS。

这种模式适用于每个伪类修饰符,例如 peer-focuspeer-requiredpeer-disabled

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

✘ 无法工作,只有前一个兄弟节点可以标记为对等节点

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

同级的区分

当使用多个同级时,您可以通过为该对等方使用 peer/{name} 类赋予该对等方一个唯一的名称,并在修改器中包含该名称,从而在特定同级的状态上设置样式,使用类似 peer-checked/{name} 的类:

Published status
html
<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。

任意的同级

您可以通过在方括号中提供自己的选择器作为任意值,即时创建一次性的修饰符。

html
<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>
css
.peer.is-dirty:required ~ .peer-\[\.is-dirty\]\:peer-required\:block {
  display: block;
}

为了更好地控制,您可以使用 & 字符来标记 .peer 在最终选择器中相对于您传入的选择器应该出现的位置:

html
<div>
  <input type="text" class="peer" />
  <div class="hidden peer-[:nth-of-type(3)_&]:block">
    <!-- ... -->
  </div>
</div>
css
:nth-of-type(3) .peer ~ .peer-\[\:nth-of-type\(3\)_\&\]\:block {
  display: block;
}

为直接子元素添加样式(*-{modifier})

虽然通常更好的做法是直接在子元素上放置实用类,但在需要样式化无法控制的直接子元素的情况下,您可以使用 * 修饰符。

Categories

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

重要的是要注意,直接在子元素上使用实用程序覆盖样式是行不通的,因为生成的子选择器的特异性。

✘ 不起作用,孩子们无法覆盖自己的样式。

html
<ul class="*:bg-sky-50 ...">
  <li class="bg-red-50 ...">Sales</li>
  <li>Marketing</li>
  <li>SEO</li>
  <!-- ... -->
</ul>

基于后代元素的样式(has-{modifier})

使用 has-* 修饰符根据其后代的状态或内容来设置元素的样式。

Payment method
html
<label class="has-[:checked]:bg-indigo-50 has-[:checked]:text-indigo-900 has-[:checked]:ring-indigo-200 ..">
  <svg fill="currentColor">
    <!-- ... -->
  </svg>
  Google Pay
  <input type="radio" class="checked:border-indigo-500 ..." />
</label>

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

基于一组后代的样式(group-has-{modifier})

如果您需要根据父元素的后代元素来设置元素样式,您可以使用 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.

html
<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-has-{modifier})

如果您需要根据兄弟元素的后代来设置元素样式,您可以使用 peer 类标记兄弟元素,并使用 peer-has-* 修饰符来设置目标元素的样式。

Today
html
<fieldset>
  <legend>Today</legend>

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

  <!-- ... -->
</fieldset>

伪元素

Before 和 After

使用 beforeafter 修饰符来设置 ::before::after 伪元素的样式:

html
<label class="block">
  <span class="after:content-['*'] after:ml-0.5 after:text-red-500 block text-sm font-medium text-slate-700">
    Email
  </span>
  <input type="email" name="email" class="mt-1 px-3 py-2 bg-white border shadow-sm border-slate-300 placeholder-slate-400 focus:outline-none focus:border-sky-500 focus:ring-sky-500 block w-full rounded-md sm:text-sm focus:ring-1" placeholder="you@example.com" />
</label>

在使用这些修饰符时,Tailwind 默认会自动添加 content: '' ,因此除非你想要不同的值,否则无需指定。

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

值得注意的是,在 Tailwind 项目中,大多数情况下你实际上并不需要 ::before::after 伪元素——通常更简单的做法是直接使用真实的 HTML 元素。

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

html
<blockquote class="text-2xl font-semibold italic text-center text-slate-900">
  When you look
  <span class="relative">
    <span class="block absolute -inset-1 -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中,用户也无法选择它。

请注意,如果您已禁用了我们的预设基本样式,内容属性将不会默认设置为空字符串,您需要在使用 beforeafter 修饰符时包含 content-['']

💡 如果您已禁用预检查,请确保手动设置内容

html
<div class="before:content-[''] before:block ...">
  <!-- ... -->
</div>

占位符文本

使用 placeholder 修饰符来为任何输入或文本区域的占位符文本设置样式:

html
<label class="relative block">
  <span class="sr-only">Search</span>
  <span class="absolute inset-y-0 left-0 flex items-center pl-2">
    <svg class="h-5 w-5 fill-slate-300" viewBox="0 0 20 20"><!-- ... --></svg>
  </span>
  <input class="placeholder:italic placeholder:text-slate-400 block bg-white w-full border border-slate-300 rounded-md py-2 pl-9 pr-3 shadow-sm focus:outline-none focus:border-sky-500 focus:ring-sky-500 focus:ring-1 sm:text-sm" placeholder="Search for anything..." type="text" name="search"/>
</label>

文件选择按钮

使用 file 修饰符来设置文件输入中的按钮样式:

Current profile photo
html
<form class="flex items-center space-x-6">
  <div class="shrink-0">
    <img class="h-16 w-16 object-cover rounded-full" src="/images/tailwindcss/photo-1580489944761.jpg" alt="Current profile photo" />
  </div>
  <label class="block">
    <span class="sr-only">Choose profile photo</span>
    <input type="file" class="block w-full text-sm text-slate-500
      file:mr-4 file:py-2 file:px-4
      file:rounded-full file:border-0
      file:text-sm file:font-semibold
      file:bg-violet-50 file:text-violet-700
      hover:file:bg-violet-100
    "/>
  </label>
</form>

请注意,Tailwind 的边框重置不适用于文件输入按钮。这意味着要向文件输入按钮添加边框,您需要显式地使用类似 file:border-solid 的类来设置边框样式,同时使用任何边框宽度实用程序:

html
<input type="file" class="file:border file:border-solid ..." />

列表标记

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

Ingredients

  • 5 cups chopped Porcini mushrooms
  • 1/2 cup of olive oil
  • 3lb of celery
html
<ul role="list" class="marker:text-sky-400 list-disc pl-5 space-y-3 text-slate-500">
  <li>5 cups chopped Porcini mushrooms</li>
  <li>1/2 cup of olive oil</li>
  <li>3lb of celery</li>
</ul>

我们设计了 marker 修饰符可继承,因此虽然您可以直接在 <li> 元素上使用它,但也可以在父元素上使用,以避免重复。

高亮的文字

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

html
<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
<html>
<head>
  <!-- ... -->
</head>
<body class="selection:bg-pink-300">
  <!-- ... -->
</body>
</html>

首行和首字母

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

html
<p class="first-line:uppercase first-line:tracking-widest
  first-letter:text-7xl first-letter:font-bold first-letter:text-slate-900
  first-letter:mr-3 first-letter:float-left
">
  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.
</p>

弹窗背景

使用 backdrop 修饰符来为本地 <dialog> 元素设置背景。

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

如果您在项目中使用原生的 <dialog> 元素,您可能还想了解如何使用 open 修饰符来设置开/闭状态的样式。

媒体和特征查询

响应式断点

要在特定断点上设置元素样式,请使用响应式修饰符,如 mdlg

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

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

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

偏爱色彩方案

这个 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.

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

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

偏好减少动作

这个 prefers-reduced-motion 媒体查询告诉您用户是否要求您最小化非必要的动作。

使用 motion-reduce 修饰符在用户请求减少动作时有条件地添加样式:

👆 尝试在开发者工具中模拟 prefers-reduced-motion: reduce 以隐藏旋转器

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

Tailwind 还包括一个 motion-safe 修饰符,只在用户未要求减少动作时添加样式。当使用 motion-reduce 助手意味着需要“撤销”大量样式时,这可能很有用:

html
<!-- 使用 `motion-reduce` 可能意味着要 "撤销 "很多样式 -->
<button class="hover:-translate-y-0.5 transition motion-reduce:hover:translate-y-0 motion-reduce:transition-none ...">
  Save changes
</button>

<!-- 在这些情况下,使用 `motion-safe` 可以减少代码量 -->
<button class="motion-safe:hover:-translate-x-0.5 motion-safe:transition ...">
  Save changes
</button>

更喜欢对比

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

使用 contrast-more 修饰符在用户要求更多对比度时有条件地添加样式:

👆 尝试在开发者工具中模拟 prefers-contrast: more,以查看更改

We need this to steal your identity.

html
<form>
  <label class="block">
    <span class="block text-sm font-medium text-slate-700">Social Security Number</span>
    <input class="border-slate-200 placeholder-slate-400 contrast-more:border-slate-400 contrast-more:placeholder-slate-500"/>
    <p class="mt-2 opacity-10 contrast-more:opacity-100 text-slate-600 text-sm">
      We need this to steal your identity.
    </p>
  </label>
</form>

Tailwind 还包括一个 contrast-less 修饰符,您可以使用它在用户要求较低对比度时有条件地添加样式。

强制颜色模式

这个 forced-colors 媒体查询指示用户是否正在使用强制颜色模式。这些模式会使用用户定义的调色板来覆盖您网站的文本、背景、链接和按钮颜色。

使用 forced-colors 修饰符在用户启用强制颜色模式时有条件地添加样式:

尝试在开发者工具中模拟 forced-colors: active 以查看更改。

Choose a theme:
html
<form>
  <legend> Choose a theme: </legend>
  <label>
    <input type="radio" class="forced-colors:appearance-auto appearance-none" />
    <p class="forced-colors:block hidden">
      Cyan
    </p>
    <div class="forced-colors:hidden h-6 w-6 rounded-full bg-cyan-200 ..."></div>
    <div class="forced-colors:hidden h-6 w-6 rounded-full bg-cyan-500 ..."></div>
  </label>
  <!-- ... -->
</form>

Tailwind 还包括强制颜色调整实用程序,以选择是否强制使用颜色。

视口方向

使用 portraitlandscape 修饰符,在特定方向的视口中有条件地添加样式:

html
<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 修饰符来有条件地添加样式,仅在文档打印时应用:

html
<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-[...] 修饰符根据用户浏览器是否支持某个特定功能来设置样式。

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

在幕后, supports-[...] 修饰符生成 @supports rules ,并接受方括号中使用 @supports (...) 的任何内容,例如属性/值对,甚至使用 andor 的表达式。

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

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

您可以在项目的 tailwind.config.js 文件的 theme.supports 部分配置常用规则的快捷方式:

js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    supports: {
      grid: 'display: grid',
    },
  },
}

您可以在项目中使用这些自定义 supports-* 修饰符:

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

属性选择器

ARIA 规定

使用 aria-* 修饰符根据 ARIA 属性有条件地设置样式。

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

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

默认情况下,我们已经包含了最常见的布尔型 ARIA 属性的修饰符:

ModifierCSS
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”]

您可以通过编辑您的 tailwind.config.js 文件来自定义可用的 aria-* 修饰符。

js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    extend: {
      aria: {
        asc: 'sort="ascending"',
        desc: 'sort="descending"',
      },
    },
  },
};

如果您需要使用一次性的 aria 修改器,而这些修改器在您的主题中没有意义,或者需要更复杂的需要特定值的 ARIA 属性,可以使用方括号来使用任意值动态生成属性。

Invoice # ClientAmount
#100Pendant Publishing$2,000.00
#101Kruger Industrial Smoothing$545.00
#102J. Peterman$10,000.25
html
<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>
css
.aria-\[sort\=ascending\]\:bg-\[url\(\'\/img\/down-arrow\.svg\'\)\][aria-sort=ascending] {
  background-image: url('/img/down-arrow.svg');
}

.aria-\[sort\=descending\]\:bg-\[url\(\'\/img\/up-arrow\.svg\'\)\][aria-sort=descending] {
  background-image: url('/img/up-arrow.svg');
}

ARIA 状态修饰符也可以使用 group-aria-*peer-aria-* 修饰符来定位父元素和兄弟元素:

html
<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>
css
.group[aria-sort=ascending] .group-aria-\[sort\=ascending\]\:rotate-0 {
  --tw-rotate: 0deg;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.group[aria-sort=descending] .group-aria-\[sort\=descending\]\:rotate-180 {
  --tw-rotate: 180deg;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

数据属性

使用 data-* 修饰符根据数据属性有条件地应用样式。

由于没有标准的 data-* 属性定义,因此默认情况下我们只支持开箱即用的任意值,例如:

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

您可以在项目中使用的常见数据属性选择器的 theme.data 部分中配置快捷方式:tailwind.config.js 文件

js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    data: {
      checked: 'ui~="checked"',
    },
  },
}

您可以在项目中使用这些自定义 data-* 修饰符:

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

RTL 支持

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

Left-to-right

Tom Cook

Director of Operations

Right-to-left

تامر كرم

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

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

请注意,除非将 dir 属性明确设置为 ltr ,否则 ltr 修饰符将不会生效,因此,如果您正在构建一个多方向网站,请确保始终设置方向,而不仅仅是在 rtl 模式中。

💡 始终设定方向,即使从左到右是你的默认方向

html
<html dir="ltr">
    <!-- ... -->
</html>

请记住,这些修饰符只在构建需要支持从左到右和从右到左布局的网站时才有用。如果您正在构建只需要支持单一方向的网站,您就不需要这些修饰符——只需应用适合您内容的样式即可。

开 / 关状态

使用 open 修饰符在 <details><dialog> 元素处于打开状态时有条件地添加样式:

👆 尝试切换披露以查看样式变化

Why do they call it Ovaltine?

The mug is round. The jar is round. They should call it Roundtine.

html
<div class="max-w-lg mx-auto p-8">
  <details class="open:bg-white dark:open:bg-slate-900 open:ring-1 open:ring-black/5 dark:open:ring-white/10 open:shadow-lg p-6 rounded-lg" open>
    <summary class="text-sm leading-6 text-slate-900 dark:text-white font-semibold select-none">
      Why do they call it Ovaltine?
    </summary>
    <div class="mt-3 text-sm leading-6 text-slate-600 dark:text-slate-400">
      <p>The mug is round. The jar is round. They should call it Roundtine.</p>
    </div>
  </details>
</div>

自定义修饰符

使用任意变体

就像任意值让您可以在实用类中使用自定义值一样,任意变体让您可以直接在HTML中编写自定义选择器修饰符。

任意变体只是代表选择器的格式字符串,用方括号括起来。例如,这个任意修饰符只选择元素当它是第三个子元素:

html
<ul role="list">
  {#each items as item}
    <li class="[&:nth-child(3)]:underline">{item}</li>
  {/each}
</ul>
css
/* https://media.giphy.com/media/uPnKU86sFa2fm/giphy.gif */
.\[\&\:nth-child\(3\)\]\:underline:nth-child(3) {
  text-decoration-style: underline
}

格式字符串与您在 addVariant 插件 API 中使用的相同,其中 & 代表被修改的选择器。

任意变体可以与内置修饰符或彼此堆叠,就像Tailwind中的其他修饰符一样。

html
<ul role="list">
  {#each items as item}
    <li class="lg:[&:nth-child(3)]:hover:underline">{item}</li>
  {/each}
</ul>
css
/* https://media.giphy.com/media/Sd3cd0SrUKZEyWmAlM/giphy.gif */
@media (min-width: 1024px) {
  .lg\:\[\&\:nth-child\(3\)\]\:hover\:underline:hover:nth-child(3) {
    text-decoration-line: underline;
  }
}

如果您需要在选择器中使用空格,可以使用下划线。例如,这个任意修改器选择在您添加了类的元素内的所有 p 元素:

html
<div class="[&_p]:mt-4">
  <p>Lorem ipsum...</p>
  <ul>
    <li>
      <p>Lorem ipsum...</p>
    </li>
    <!-- ... -->
  </ul>
</div>
css
.\[\&_p\]\:mt-4 p {
    margin-top: 1rem;
}

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

html
<div class="flex [@supports(display:grid)]:grid">
  <!-- ... -->
</div>
css
/* https://media.giphy.com/media/sEms56zTGDx96/giphy.gif */
@supports (display: grid) {
  .\[\@supports\(display\:grid\)\]\:grid {
    display: grid;
  }
}

使用 at-rule 自定义修饰符时, & 占位符是不必要的,就像在预处理器中嵌套时一样。

你甚至可以通过在 at 规则后的花括号中包含选择器修饰符来结合 at 规则和常规选择器修饰符:

html
<button type="button" class="[@media(any-hover:hover){&:hover}]:opacity-100">
  <!-- ... -->
</button>
css
/* https://media.giphy.com/media/l0IypeKl9NJhPFMrK/giphy.gif */
@media (any-hover: hover) {
  .\[\@media\(any-hover\:hover\)\{\&\:hover\}\]\:opacity-100:hover {
    opacity: 1
  }
}

创建一个插件

如果你发现自己在项目中多次使用相同的任意修饰符,可能值得使用 addVariant API 将其提取到插件中:

js
let plugin = require('tailwindcss/plugin')

module.exports = {
  // ...
  plugins: [
    plugin(function ({ addVariant }) {
      // Add a `third` variant, ie. `third:pb-0`
      addVariant('third', '&:nth-child(3)')
    })
  ]
}

添加变体插件文档中了解更多信息。

高级主题

使用你自己的类

只要您在 Tailwind 的图层之一中定义了自定义类,或者使用插件添加了它们,就可以使用 Tailwind 的所有修饰符。

css
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer utilities {
  .content-auto {
    content-visibility: auto;
  }
}
html
<div class="lg:content-auto">
  <!-- ... -->
</div>

堆叠修饰符的排序

当堆叠修饰符时,它们会从内向外应用,就像嵌套函数调用一样:

css
// These modifiers:
'dark:group-hover:focus:opacity-100'

// ...are applied like this:
dark(groupHover(focus('opacity-100')))

在大多数情况下,这实际上并不重要,但有一些情况下,您使用的顺序会产生具有实质性差异的CSS。

例如,如果您已将 darkMode 配置为 class ,那么结合 darkgroup-hover 修饰符的顺序不同,会产生不同的结果:

css
/* dark:group-hover:opacity-100 */
.dark .group:hover .dark\:group-hover\:opacity-100 {
  opacity: 1;
}

/* group-hover:dark:opacity-100 */
.group:hover .dark .group-hover\:dark\:opacity-100 {
  opacity: 1;
}

在第一个例子中, dark 元素需要成为 group 元素的父元素,但在第二个例子中则相反。

另一个重要的地方是在使用与官方排版插件一起包含的修饰符 prose-headings 时。

css
/* prose-headings:hover:underline */
.prose-headings\:hover\:underline:hover :is(:where(h1, h2, h3, h4, th)) {
  text-decoration: underline;
}

/* hover:prose-headings:underline */
.hover\:prose-headings\:underline :is(:where(h1, h2, h3, h4, th)):hover {
  text-decoration: underline;
}

在第一个例子中,当你悬停在文章本身上时,每个标题都会被划线,而在第二个例子中,只有当你悬停在标题上时,该标题才会被划线。

附录

快速参照

Tailwind 默认包含的每个修饰符的快速参照表。

ModifierCSS
hover&:hover
focus&:focus
focus-within&:focus-within
focus-visible&:focus-visible
active&:active
visited&:visited
target&:target
*& > *
has&:has
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
empty&:empty
disabled&:disabled
enabled&:enabled
checked&:checked
indeterminate&:indeterminate
default&:default
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
selection&::selection
file&::file-selector-button
backdrop&::backdrop
placeholder&::placeholder
sm@media (min-width: 640px)
md@media (min-width: 768px)
lg@media (min-width: 1024px)
xl@media (min-width: 1280px)
2xl@media (min-width: 1536px)
min-[]@media (min-width: )
max-sm@media not all and (min-width: 640px)
max-md@media not all and (min-width: 768px)
max-lg@media not all and (min-width: 1024px)
max-xl@media not all and (min-width: 1280px)
max-2xl@media not all and (min-width: 1536px)
max-[]@media (max-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-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&[open]

伪类引用

这是一个包含了 Tailwind 中所有伪类修饰符示例的综合列表,以补充本指南开头的伪类文档。

hover (:hover)

当用户用鼠标悬停在元素上时,使用 hover 修饰符来设置样式:

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

focus (:focus)

使用 focus 修饰符在元素获得焦点时设置样式:

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

focus-within (:focus-within)

当元素本身或其后代元素获得焦点时,使用 focus-within 修饰符来设置样式:

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

focus-visible (:focus-visible)

使用键盘聚焦时,使用 focus-visible 修饰符来设置元素的样式:

html
<button class="focus:outline-none focus-visible:ring ...">
  Submit
</button>

active (:active)

在元素被按下时使用 active 修饰符来设置样式:

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

visited (:visited)

使用 visited 修饰符来为已访问过的链接设置样式:

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

target (:target)

如果元素的 ID 与当前 URL 片段匹配,则使用 target 修饰符样式化该元素:

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

first (:first-child)

如果它是第一个子元素,则使用 first 修饰符来为元素设置样式。

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

last (:last-child)

如果它是最后一个子元素,则使用 last 修饰符来设置元素的样式。

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

only (:only-child)

如果它是唯一的子元素,则使用 only 修饰符来设置元素的样式。

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

odd (:nth-child(odd))

如果它是奇数编号的子元素,则使用 odd 修饰符来设置元素的样式:

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

even (:nth-child(even))

如果它是偶数编号的子元素,则使用 even 修饰符来设置元素的样式:

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

first-of-type (:first-of-type)

如果元素是其类型的第一个子元素,则使用 first-of-type 修饰符来设置样式:

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

last-of-type (:last-of-type)

如果它是其类型的最后一个子元素,则使用 last-of-type 修饰符来设置元素的样式:

html
<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>
</table>

only-of-type (:only-of-type)

如果元素是其类型的唯一子元素,则使用 only-of-type 修饰符来设置样式:

html
<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>
</table>

empty (:empty)

使用 empty 修饰符为没有内容的元素设计样式:

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

disabled (:disabled)

使用 disabled 修饰符在输入框被禁用时设置样式:

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

enabled (:enabled)

当输入启用时,使用 enabled 修饰符为输入框添加样式,这在只想在元素未禁用时应用另一种样式时非常有用:

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

checked (:checked)

使用 checked 修饰符来设置复选框或单选按钮的选中样式:

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

indeterminate (:indeterminate)

使用 indeterminate 修饰符来设置复选框或单选按钮的不确定状态样式:

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

default (:default)

使用 default 修饰符来设置页面初始加载时作为默认值的选项、复选框或单选按钮的样式:

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

required (:required)

使用 required 修饰符来设置必填输入的样式:

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

valid (:valid)

当输入有效时,使用 valid 修饰符为输入框添加样式:

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

invalid (:invalid)

当输入无效时,使用 invalid 修饰符为输入框添加样式:

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

in-range (:in-range)

当输入值在指定范围限制内时,使用 in-range 修饰符来设置样式:

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

out-of-range (:out-of-range)

当输入值超出指定范围限制时,使用 out-of-range 修饰符来设置样式:

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

placeholder-shown (:placeholder-shown)

当占位符显示时,使用 placeholder-shown 修饰符来设置输入框的样式。

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

autofill (:autofill)

当浏览器使用 autofill 修改器自动填充输入内容时,为输入框设置样式:

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

read-only (:read-only)

使用 read-only 修饰符为只读时,为输入框设置样式:

html
<input class="read-only:bg-gray-100 ..." />

Released under the MIT License.