Core concepts
使用工具类来设置元素在悬停、焦点和其他状态下的样式。
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 和 ::selectionprefers-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
Floyd Miles
Courtney Henry
Ted Fox
<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 | [email protected] |
| Cody Fisher | Product Directives Officer | [email protected] |
| Leonard Krasner | Senior Designer | [email protected] |
| Emily Selman | VP, Hardware Engineering | [email protected] |
| Anna Roberts | Chief Strategy Officer | [email protected] |
<table> <!-- ... --> <tbody> {#each people as person} <!-- Use different background colors for odd and even rows --> <tr class="odd:bg-white even:bg-gray-50 dark:odd:bg-gray-900/50 dark:even:bg-gray-950"> <td>{person.name}</td> <td>{person.title}</td> <td>{person.email}</td> </tr> {/each} </tbody></table>使用 nth-* 和 nth-last-* 变体根据元素在列表中的位置设置样式:
<div class="nth-3:underline"> <!-- ... --></div><div class="nth-last-5:underline"> <!-- ... --></div><div class="nth-of-type-4:underline"> <!-- ... --></div><div class="nth-last-of-type-6:underline"> <!-- ... --></div>默认情况下,你可以传递任何数字,并使用任意值来实现更复杂的表达式,如 nth-[2n+1_of_li]。
Tailwind 还包括其他结构性伪类的变体,如 :only-child、:first-of-type、:empty 等。
请参阅伪类参考以获取可用伪类变体的完整列表。
使用 required、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"> Published </div></div>为了更好的控制,你可以使用 & 字符来标记 .group 在你传递的选择器中相对于最终选择器的位置:
<div class="group"> <div class="group-[:nth-of-type(3)_&]:block"> <!-- ... --> </div></div>in-* 变体的工作方式类似于 group,但你不需要向父元素添加 group:
<div tabindex="0" class="group"> <div class="opacity-50 group-focus:opacity-100"> <div tabindex="0"> <div class="opacity-50 in-focus:opacity-100"> <!-- ... --> </div> </div> </div></div>in-* 变体响应任何父元素的状态变化,所以如果你想要更细粒度的控制,你需要使用 group 代替。
当你需要根据某个同级元素的状态来设置元素的样式时,使用 peer 类标记同级元素,并使用 peer-* 变体如 peer-invalid 来设置目标元素的样式:
尝试使邮箱地址有效以查看警告消失
<form> <label class="block"> <span class="...">Email</span> <input type="email" class="peer ..." /> <p class="invisible peer-invalid:visible ...">Please provide a valid email address.</p> </label></form>这使得可以做各种有趣的技巧,例如浮动标签而无需任何 JS。
这种模式适用于每个伪类变体,例如 peer-focus、peer-required 和 peer-disabled。
重要的是要注意,peer 标记只能用于前面的同级元素,因为后续同级选择器在 CSS 中的工作方式:
不起作用,只有前面的同级元素可以标记为同级
<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="[email protected]" /></label>使用这些变体时,Tailwind 会自动添加 content: '' 作为默认值,因此你不必指定它,除非你想要一个不同的值:
When you look annoyed all the time, people think that you're busy.
<blockquote class="text-center text-2xl font-semibold text-gray-900 italic dark:text-white"> When you look <span class="relative inline-block before:absolute before:-inset-1 before:block before:-skew-y-3 before:bg-pink-500"> <span class="relative text-white dark:text-gray-950">annoyed</span> </span> all the time, people think that you're busy.</blockquote>值得注意的是,在 Tailwind 项目中,你实际上不需要 ::before 和 ::after 伪元素来完成大多数事情 — 通常使用一个真实的 HTML 元素会更简单。
例如,这里是上面的相同设计,但使用 <span> 而不是 ::before 伪元素,这更容易阅读,实际上代码更少:
<blockquote class="text-center text-2xl font-semibold text-gray-900 italic"> When you look <span class="relative"> <span class="absolute -inset-1 block -skew-y-3 bg-pink-500" aria-hidden="true"></span> <span class="relative text-white">annoyed</span> </span> all the time, people think that you're busy.</blockquote>将 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 辅助函数需要“撤销”许多样式时非常有用:
<!-- 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 还包括一个强制颜色调整工具类,以选择加入和退出强制颜色。
使用 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>使用 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 属性的变体:
| 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-* 变体根据数据属性有条件地应用样式。
要检查数据属性是否存在(而不是特定值),你可以只指定属性名称:
<!-- 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-* 命名空间中创建一个新变体来配置项目中常用的数据属性的快捷方式:
@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">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>你还可以在任意变体中使用 @media 或 @supports 等 at 规则:
<div class="flex [@supports(display:grid)]:grid"> <!-- ... --></div>使用 at 规则自定义变体时,不需要 & 占位符,就像使用预处理器嵌套时一样。
如果你发现自己在项目中多次使用相同的任意变体,可能值得创建一个自定义变体:
@custom-variant pointer-coarse { @media (pointer: coarse) { @slot; }}现在你可以在 HTML 中使用 pointer-coarse:<utility> 变体:
<button class="pointer-coarse:size-12 ..."></button>当不需要嵌套时,可以使用简写语法创建变体:
@custom-variant pointer-coarse (@media (pointer: coarse));当自定义变体有多个规则时,它们可以相互嵌套:
@custom-variant any-hover { @media (any-hover: hover) { &:hover { @slot; } }}这是一个包含 Tailwind 默认包含的每个变体的快速参考表。
| 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 |
| in-range | &:in-range |
| out-of-range | &:out-of-range |
| placeholder-shown | &:placeholder-shown |
| autofill | &:autofill |
| read-only | &:read-only |
| before | &::before |
| after | &::after |
| first-letter | &::first-letter |
| first-line | &::first-line |
| marker | &::marker, & *::marker |
| selection | &::selection |
| file | &::file-selector-button |
| backdrop | &::backdrop |
| placeholder | &::placeholder |
| sm | @media (width >= 40rem) |
| md | @media (width >= 48rem) |
| lg | @media (width >= 64rem) |
| xl | @media (width >= 80rem) |
| 2xl | @media (width >= 96rem) |
| min-[...] | @media (width >= ...) |
| max-sm | @media (width < 40rem) |
| max-md | @media (width < 48rem) |
| max-lg | @media (width < 64rem) |
| max-xl | @media (width < 80rem) |
| max-2xl | @media (width < 96rem) |
| max-[...] | @media (width < ...) |
| @3xs | @container (width >= 16rem) |
| @2xs | @container (width >= 18rem) |
| @xs | @container (width >= 20rem) |
| @sm | @container (width >= 24rem) |
| @md | @container (width >= 28rem) |
| @lg | @container (width >= 32rem) |
| @xl | @container (width >= 36rem) |
| @2xl | @container (width >= 42rem) |
| @3xl | @container (width >= 48rem) |
| @4xl | @container (width >= 56rem) |
| @5xl | @container (width >= 64rem) |
| @6xl | @container (width >= 72rem) |
| @7xl | @container (width >= 80rem) |
| @min-[...] | @container (width >= ...) |
| @max-3xs | @container (width < 16rem) |
| @max-2xs | @container (width < 18rem) |
| @max-xs | @container (width < 20rem) |
| @max-sm | @container (width < 24rem) |
| @max-md | @container (width < 28rem) |
| @max-lg | @container (width < 32rem) |
| @max-xl | @container (width < 36rem) |
| @max-2xl | @container (width < 42rem) |
| @max-3xl | @container (width < 48rem) |
| @max-4xl | @container (width < 56rem) |
| @max-5xl | @container (width < 64rem) |
| @max-6xl | @container (width < 72rem) |
| @max-7xl | @container (width < 80rem) |
| @max-[...] | @container (width < ...) |
| dark | @media (prefers-color-scheme: dark) |
| portrait | @media (orientation: portrait) |
| landscape | @media (orientation: landscape) |
| motion-safe | @media (prefers-reduced-motion: no-preference) |
| motion-reduce | @media (prefers-reduced-motion: reduce) |
| contrast-more | @media (prefers-contrast: more) |
| contrast-less | @media (prefers-contrast: less) |
@media print | |
| supports-[…] | @supports (…) |
| aria-busy | &[aria-busy="true"] |
| aria-checked | &[aria-checked="true"] |
| aria-disabled | &[aria-disabled="true"] |
| aria-expanded | &[aria-expanded="true"] |
| aria-hidden | &[aria-hidden="true"] |
| aria-pressed | &[aria-pressed="true"] |
| aria-readonly | &[aria-readonly="true"] |
| aria-required | &[aria-required="true"] |
| aria-selected | &[aria-selected="true"] |
| aria-[…] | &[aria-…] |
| data-[...] | &[data-...] |
| rtl | [dir="rtl"] & |
| ltr | [dir="ltr"] & |
| open | &:is([open], :popover-open) |
| forced-colors | @media (forced-colors: active) |
| starting | @starting-style |
这是一个包含所有伪类变体示例的综合列表,以补充本指南开头的伪类文档。
使用 hover 变体在用户将鼠标悬停在元素上时设置样式:
<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>使用 target 变体在元素的 ID 与当前 URL 片段匹配时设置样式:
<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 ..." />使用 default 变体在选项、复选框或单选按钮是页面初始加载时的默认值时设置样式:
<input type="checkbox" class="default:outline-2 ..." />使用 optional 变体在输入是可选时设置样式:
<input class="optional:border-red-500 ..." />使用 required 变体在输入是必填时设置样式:
<input class="required:border-red-500 ..." />使用 valid 变体在输入有效时设置样式:
<input class="valid:border-green-500 ..." />使用 invalid 变体在输入无效时设置样式:
<input class="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="[email protected]" />使用 autofill 变体在输入已被浏览器自动填充时设置样式:
<input class="autofill:bg-yellow-200 ..." />使用 read-only 变体在输入为只读时设置样式:
<input class="read-only:bg-gray-100 ..." />