核心概念
使用工具类为悬停、聚焦等状态的元素进行样式设置。
Tailwind 中的每个工具类都可以通过在类名开头添加描述目标条件的变体来进行 条件 应用。
例如,为了在悬停时应用 bg-sky-700 类,可以使用 hover:bg-sky-700 类:
悬停在此按钮上以查看背景颜色变化
<button class="bg-sky-500 hover:bg-sky-700 ...">保存更改</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 和 ::selectionprefers-reduced-motion[dir="rtl"] 和 [open]& > * 和 & *这些变体甚至可以叠加使用,以应对更特定的情况,例如在暗模式下、在中等断点下、在悬停时更改背景颜色:
<button class="dark:md:hover:bg-fuchsia-600 ...">保存更改</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 ..."> 保存更改</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 变体为奇数和偶数子元素设置样式:
| Name | Title | |
|---|---|---|
| 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 |
<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-* 变体为目标元素设置样式:
Just happy to be here.
A multidisciplinary designer, working at the intersection of art and technology.
alex-reed.com
Pushing pixels. Slinging divs.
<div class="group ..."> <img src="..." /> <h4>Spencer Sharp</h4> <svg class="hidden group-has-[a]:block ..."><!-- ... --></svg> <p>Product Designer at <a href="...">planeteria.tech</a></p></div>如果您需要根据一个兄弟元素的后代为元素设置样式,可以使用 peer 类标记该兄弟,并使用 peer-has-* 变体为目标元素设置样式:
<div> <label class="peer ..."> <input type="checkbox" name="todo[1]" checked /> 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"> 已发布 </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。
重要的是要注意,因为 后续兄弟组合器 的工作方式,peer 标记只能用于 先前 的兄弟:
不适用,只有前面的兄弟可以标记为同伴
<label> <span class="peer-invalid:text-red-500 ...">电子邮件</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-['*'] ...">电子邮件</span> <input type="email" name="email" class="..." placeholder="you@example.com" /></label>使用这些变体时,Tailwind 将默认自动添加 content: '',因此除非您想要其他值,否则您不必指定:
当你看起来 烦恼 时,人们会觉得你忙得不可开交。
<blockquote class="text-center text-2xl font-semibold text-gray-900 italic dark:text-white"> 当你看起来 <span class="relative inline-block before:absolute before:-inset-1 before:block before:-skew-y-3 before:bg-pink-500"> <span class="relative text-white dark:text-gray-950">烦恼</span> </span> 时,人们会觉得你忙得不可开交。</blockquote>值得注意的是,在大多数 Tailwind 项目中,您实际上并不需要 ::before 和 ::after 伪元素——通常直接使用真实的 HTML 元素会更简单。
例如,这里是上面相同设计的实现,但使用 <span> 而不是 ::before 伪元素,这样会更容易理解并且代码量实际上更少:
<blockquote class="text-center text-2xl font-semibold text-gray-900 italic"> 当你看起来 <span class="relative"> <span class="absolute -inset-1 block -skew-y-3 bg-pink-500" aria-hidden="true"></span> <span class="relative text-white">烦恼</span> </span> 时,人们会觉得你忙得不可开交。</blockquote>将 before 和 after 保留用于那些内容重要到伪元素内容不实际上存在于 DOM 中并且无法被用户选择的情况。
使用 placeholder 变体为任何输入或文本区域的占位符文本设置样式:
<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 变体为活动文本选择设置样式:
尝试用鼠标选择一些文本
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 变体为第一字符设置样式:
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 变体为 原生 <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 变体为暗色模式提供覆盖:
Light mode
The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.
Dark mode
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 媒体查询告诉您用户是否请求最小化非必要的运动。
使用 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 帮助程序意味着必须“撤消”很多样式时,这可能非常有用:
<!-- 使用 `motion-reduce` 可能意味着撤销很多样式 --><button class="transition hover:-translate-y-0.5 motion-reduce:transition-none motion-reduce:hover:translate-y-0 ..."> 保存更改</button><!-- 在这些情况下使用 `motion-safe` 则代码更少 --><button class="motion-safe:transition motion-safe:hover:-translate-x-0.5 ...">保存更改</button>prefers-contrast 媒体查询告诉您用户是否请求更高或更低的对比度。
使用 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 also includes a forced color adjust utilities to opt in and out of forced colors.
Use the inverted-colors variant to conditionally add styles when the user has enabled an inverted color scheme:
<div class="shadow-xl inverted-colors:shadow-none ..."> <!-- ... --></div>The pointer media query tells you whether the user has a primary pointing device, like a mouse, and the accuracy of that pointing device.
Use the pointer-fine variant to target an accurate pointing device, like a mouse or trackpad, or the pointer-coarse variant to target a less accurate pointing device, like a touchscreen, which can be useful for providing larger click targets on touch devices:
Try emulating a touch device in your developer tools to see the changes
<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>While pointeronly targets the primary pointing device, any-pointer is used to target any of the pointing devices that might be available. Use the any-pointer-fine and any-pointer-coarse variants to provide different styles if at least one connected pointing device meets the criteria.
You can use pointer-none and any-pointer-none to target the absence of a pointing device.
使用 portrait 和 landscape 变体在视口处于特定方向时条件性地添加样式:
<div> <div class="portrait:hidden"> <!-- ... --> </div> <div class="landscape:hidden"> <p>此体验设计为横屏查看。请旋转您的设备以查看网站。</p> </div></div>Use the noscript variant to conditionally add styles based on whether the user has scripting, such as JavaScript, enabled:
<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>我的秘密披萨食谱</h1> <p>这个食谱是秘密,不能与任何人分享</p> <!-- ... --> </article> <div class="hidden print:block">你真的想打印这东西吗?它是秘密!</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 属性包含了变体:
| Variant | 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 属性,请使用方括号通过任何任意值动态生成属性:
| Invoice # | Client | Amount |
|---|---|---|
| #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-* 变体根据 数据属性 条件性地应用样式。
要检查数据属性是否存在(而不是特定值),您只需指定属性名称即可:
<!-- 将应用 --><div data-active class="border border-gray-300 data-active:border-purple-500"> <!-- ... --></div><!-- 将不应用 --><div class="border border-gray-300 data-active:border-purple-500"> <!-- ... --></div>如果需要检查特定值,可以使用任意值:
<!-- 将应用 --><div data-size="large" class="data-[size=large]:p-8"> <!-- ... --></div><!-- 将不应用 --><div data-size="medium" class="data-[size=large]:p-8"> <!-- ... --></div>或者,您可以通过在 data-* 命名空间中创建新变体为项目中使用的常见数据属性配置快捷方式:
@import "tailwindcss";@custom-variant data-checked (&[data-ui~="checked"]);然后,您可以在项目中使用这些自定义 data-* 变体:
<div data-ui="checked active" class="data-checked:underline"> <!-- ... --></div>使用 rtl 和 ltr 变体在构建多方向布局时分别条件性地添加样式以支持从右到左和从左到右的模式:
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> 元素处于打开状态时条件性地添加样式:
尝试切换披露以查看样式变化
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">打开弹出窗口</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 ...">销售</li> <li>市场营销</li> <li>搜索引擎优化</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-rule,例如 @media 或 @supports:
<div class="flex [@supports(display:grid)]:grid"> <!-- ... --></div>在使用 at-rule 自定义变体时,& 占位符不是必需的,就像与预处理器进行嵌套时一样。
If you find yourself using the same arbitrary variant multiple times in your project, it might be worth creating a custom variant using the @custom-variant directive:
@custom-variant theme-midnight (&:where([data-theme="midnight"] *));Now you can use the theme-midnight:<utility> variant in your HTML:
<html data-theme="midnight"> <button class="theme-midnight:bg-black ..."></button></html>Learn more about adding custom variants in the adding custom variants documentation.
Tailwind 默认包含的每个变体的快速参考表。
| Variant | 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 ...">提交</button>在元素被按压时使用 active 变体为元素设置样式:
<button class="bg-blue-500 active:bg-blue-600 ...">提交</button>在链接被访问过后使用 visited 变体为元素设置样式:
<a href="https://seinfeldquotes.com" class="text-blue-600 visited:text-purple-600 ..."> 灵感 </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>更多</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>更多</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>更多</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>更多</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>更多</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>更多</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 ..." />使用 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 ..." />Style an input when it's valid and the user has interacted with it, using the user-valid variant:
<input required class="border user-valid:border-green-500" />Style an input when it's invalid and the user has interacted with it, using the user-invalid variant:
<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-shown 变体为输入中显示占位符时的样式:
<input class="placeholder-shown:border-gray-500 ..." placeholder="you@example.com" />Style the content of a <details> element using the details-content variant:
<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 ..." />