核心概念
使用实用程序在悬停、焦点等状态下设置元素样式。
Tailwind 中的每个实用程序类都可以通过在类名称的开头添加一个变体来有条件地应用,该变体描述了您要定位的条件。
例如,要在悬停时应用 bg-sky-700
类,请使用 hover:bg-sky-700
类
悬停在此按钮上以查看背景颜色变化
<button class="bg-sky-500 hover:bg-sky-700 ...">Save changes</button>
当以传统方式编写 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 包括几乎所有您需要的变体,包括
:hover
、:focus
、:first-child
和 :required
::before
、::after
、::placeholder
和 ::selection
prefers-reduced-motion
[dir="rtl"]
和 [open]
& > *
和 & *
这些变体甚至可以堆叠以定位更具体的情况,例如在暗黑模式、中等断点和悬停时更改背景颜色
<button class="dark:md:hover:bg-fuchsia-600 ...">Save changes</button>
在本指南中,您将了解框架中提供的每个变体、如何将它们与您自己的自定义类一起使用,甚至是如何创建自己的变体。
使用 hover
、focus
和 active
变体在悬停、焦点和激活状态下设置元素样式
尝试与此按钮交互以查看悬停、焦点和激活状态
<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
变体在元素是第一个子元素或最后一个子元素时设置其样式
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>
您还可以使用 odd
和 even
变体在元素是奇数或偶数子元素时设置其样式
姓名 | 职称 | 电子邮件 |
---|---|---|
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
、invalid
和 disabled
等变体在不同状态下设置表单元素的样式
尝试使电子邮件地址有效以查看样式更改
<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-*
变体根据元素后代的状态或内容设置元素的样式
<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-*
变体来设置目标元素的样式
很高兴来到这里。
推动像素。投掷 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-focus:
与 hover:
结合使用,以仅在元素未聚焦时应用悬停样式
尝试聚焦按钮,然后悬停在按钮上
<button class="bg-indigo-600 hover:not-focus:bg-indigo-700"> <!-- ... --></button>
您还可以将 not-
变体与媒体查询变体(例如 forced-colors
或 supports
)结合使用,以仅在用户的环境不为真时设置元素的样式
<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-focus
、group-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-focus
、peer-required
和 peer-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
变体设置 ::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>
将 before
和 after
保留给伪元素的内容实际上不在 DOM 中且无法被用户选择的重要情况。
使用 placeholder
变体设置任何输入或 textarea 的占位符文本的样式
<input class="placeholder:text-gray-500 placeholder:italic ..." placeholder="Search for anything..." type="text" name="search"/>
使用 file
变体设置文件输入中按钮的样式
<input type="file" class="file:mr-4 file:rounded-full file:border-0 file:bg-violet-50 file:px-4 file:py-2 file:text-sm file:font-semibold file:text-violet-700 hover:file:bg-violet-100 dark:file:bg-violet-600 dark:file:text-violet-100 dark:hover:file:bg-violet-500 ..."/>
使用 marker
变体设置列表中计数器或项目符号的样式
<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
变体设置活动文本选择的样式
尝试用鼠标选择此文本的一些内容
所以我开始走向水中。我不会对你们撒谎,孩子们,我很害怕。但我坚持了下来,当我穿过海浪时,一种奇怪的平静降临到我身上。我不知道这是神圣的干预还是所有生物之间的亲缘关系,但我告诉你杰瑞,在那一刻,我是一位海洋生物学家。
<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
变体设置第一个字母的样式
好吧,让我告诉你一些事情,有趣的家伙。你知道那个小邮戳,上面写着“纽约公共图书馆”吗?好吧,这对你来说可能没有任何意义,但这对我很重要。非常重要。
当然,如果你愿意就笑吧。我以前见过你这种类型的人:花哨,出风头,炫耀习俗。是的,我知道你在想什么。这家伙为什么对旧图书馆的书籍如此大惊小怪?好吧,让我给你一个提示,年轻人。
<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
变体设置原生 <dialog>
元素的背景幕的样式
<dialog class="backdrop:bg-gray-50"> <form method="dialog"> <!-- ... --> </form></dialog>
如果您在项目中使用原生 <dialog>
元素,您可能还想阅读有关使用 open
变体设置打开/关闭状态样式的信息。
要在特定断点处设置元素样式,请使用响应式变体,例如 md
和 lg
。
例如,这将在移动设备上呈现 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
媒体查询告诉您用户是喜欢浅色主题还是深色主题,通常在操作系统级别配置。
使用没有变体的实用程序来定位浅色模式,并使用 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
媒体查询告诉您用户是否请求您最小化非必要的运动。
当用户请求减少运动时,使用 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
媒体查询告诉您用户是否请求更多或更少的对比度。
当用户请求更高对比度时,使用 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: 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
变体有条件地添加样式
<div class="shadow-xl inverted-colors:shadow-none ..."> <!-- ... --></div>
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-fine
和 any-pointer-coarse
变体来提供不同的样式。
您可以使用 pointer-none
和 any-pointer-none
来定位缺少指点设备的情况。
当视口处于特定方向时,使用 portrait
和 landscape
变体有条件地添加样式
<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>
使用 noscript
变体根据用户是否启用了脚本(例如 JavaScript)有条件地添加样式
<div class="hidden noscript:block"> <p>This experience requires JavaScript to function. Please enable JavaScript in your browser settings.</p></div>
使用 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-[...]
变体根据用户的浏览器是否支持特定功能来设置样式
<div class="flex supports-[display:grid]:grid ..."> <!-- ... --></div>
在底层,supports-[...]
变体生成@supports 规则
,并在方括号之间接受您将与 @supports (...)
一起使用的任何内容,例如属性/值对,甚至使用 and
和 or
的表达式。
为了简洁起见,如果您只需要检查是否支持某个属性(而不是特定值),则只需指定属性名称即可
<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
变体来设置元素在 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-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 属性,请使用方括号来动态生成具有任意值的属性
发票编号 | 客户 | 金额 |
---|---|---|
#100 | Pendant Publishing | $2,000.00 |
#101 | Kruger Industrial Smoothing | $545.00 |
#102 | J. 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-*
变体根据 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 属性配置快捷方式
@import "tailwindcss";@custom-variant data-checked (&[data-ui~="checked"]);
然后您可以在项目中使用这些自定义的 data-*
变体
<div data-ui="checked active" class="data-checked:underline"> <!-- ... --></div>
在构建多方向布局时,分别使用 rtl
和 ltr
变体在从右到左和从左到右模式下有条件地添加样式
从左到右
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 以查看样式变化
杯子是圆的。罐子是圆的。他们应该叫它 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
属性的元素
<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>
这对于添加视觉提示非常有用,这些提示可以清楚地表明内容部分不是交互式的。
虽然通常最好将实用程序类直接放在子元素上,但在您需要样式化您无法控制的直接子元素的情况下,可以使用 *
变体
<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) |
@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
变体来设置元素样式
<div class="bg-black hover:bg-white ..."> <!-- ... --></div>
当元素获得焦点时,使用 focus
变体来设置元素样式
<input class="border-gray-300 focus:border-blue-400 ..." />
当元素或其后代元素之一获得焦点时,使用 focus-within
变体来设置元素样式
<div class="focus-within:shadow-lg ..."> <input type="text" /></div>
当元素使用键盘获得焦点时,使用 focus-visible
变体来设置元素样式
<button class="focus-visible:outline-2 ...">Submit</button>
当元素被按下时,使用 active
变体来设置元素样式
<button class="bg-blue-500 active:bg-blue-600 ...">Submit</button>
当链接已被访问时,使用 visited
变体来设置链接样式
<a href="https://seinfeldquotes.com" class="text-blue-600 visited:text-purple-600 ..."> Inspiration </a>
如果元素的 ID 与当前 URL 片段匹配,则使用 target
变体来设置元素样式
<div id="about" class="target:shadow-lg ..."> <!-- ... --></div>
如果元素是第一个子元素,则使用 first
变体来设置元素样式
<ul> {#each people as person} <li class="py-4 first:pt-0 ..."> <!-- ... --> </li> {/each}</ul>
如果元素是最后一个子元素,则使用 last
变体来设置元素样式
<ul> {#each people as person} <li class="py-4 last:pb-0 ..."> <!-- ... --> </li> {/each}</ul>
如果元素是唯一子元素,则使用 only
变体来设置元素样式
<ul> {#each people as person} <li class="py-4 only:py-0 ..."> <!-- ... --> </li> {/each}</ul>
如果元素是奇数编号的子元素,则使用 odd
变体来设置元素样式
<table> {#each people as person} <tr class="bg-white odd:bg-gray-100 ..."> <!-- ... --> </tr> {/each}</table>
如果元素是偶数编号的子元素,则使用 even
变体来设置元素样式
<table> {#each people as person} <tr class="bg-white even:bg-gray-100 ..."> <!-- ... --> </tr> {/each}</table>
如果元素是其类型的第一个子元素,则使用 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
变体来设置元素样式
<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
变体来设置元素样式
<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
变体来设置特定位置的元素的样式
<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
变体来设置从末尾开始的特定位置的元素的样式
<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
变体来设置相同类型的特定位置的元素的样式
<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
变体来设置从末尾开始的相同类型的特定位置的元素的样式
<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
变体来设置元素样式
<ul> {#each people as person} <li class="empty:hidden ...">{person.hobby}</li> {/each}</ul>
当输入被禁用时,使用 disabled
变体来设置输入样式
<input class="disabled:opacity-75 ..." />
当输入被启用时,使用 enabled
变体来设置输入样式,当您只想在元素未被禁用时应用另一种样式时,这最有用
<input class="enabled:hover:border-gray-400 disabled:opacity-75 ..." />
当复选框或单选按钮被选中时,使用 checked
变体来设置其样式
<input type="checkbox" class="appearance-none checked:bg-blue-500 ..." />
当复选框或单选按钮处于不确定状态时,使用 indeterminate
变体来设置其样式
<input type="checkbox" class="appearance-none indeterminate:bg-gray-300 ..." />
当页面初始加载时,如果 option、复选框或单选按钮是默认值,则使用 default
变体来设置其样式
<input type="checkbox" class="default:outline-2 ..." />
当输入为可选时,使用 optional
变体来设置输入样式
<input class="border optional:border-red-500 ..." />
当输入为必填时,使用 required
变体来设置输入样式
<input required class="border required:border-red-500 ..." />
当输入有效时,使用 valid
变体来设置输入样式
<input required class="border valid:border-green-500 ..." />
当输入无效时,使用 invalid
变体来设置输入样式
<input required class="border invalid:border-red-500 ..." />
当输入有效且用户已与之交互时,使用 user-valid
变体来设置输入样式
<input required class="border user-valid:border-green-500" />
当输入无效且用户已与之交互时,使用 user-invalid
变体来设置输入样式
<input required class="border user-invalid:border-red-500" />
当输入值在指定的范围限制内时,使用 in-range
变体来设置输入样式
<input min="1" max="5" class="in-range:border-green-500 ..." />
当输入值超出指定的范围限制时,使用 out-of-range
变体来设置输入样式
<input min="1" max="5" class="out-of-range:border-red-500 ..." />
当 placeholder 显示时,使用 placeholder-shown
变体来设置输入样式
<input class="placeholder-shown:border-gray-500 ..." placeholder="you@example.com" />
使用 details-content
变体来设置 <details>
元素的内容的样式
<details class="details-content:bg-gray-100 ..."> <summary>Details</summary> This is a secret.</details>
当输入已被浏览器自动填充时,使用 autofill
变体来设置输入样式
<input class="autofill:bg-yellow-200 ..." />
当输入为只读时,使用 read-only
变体来设置输入样式
<input class="read-only:bg-gray-100 ..." />