1. 核心概念(Core Concepts)
  2. Hover、Focus 與其他狀態(Hover, focus, and other states)

核心概念(Core Concepts)

Hover、Focus 與其他狀態(Hover, focus, and other states)

使用通用類別在 hover、focus 等狀態下設定元素樣式。

Tailwind 中的每個通用類別都可以透過在類別名稱開頭加上描述目標條件的變體(variant)來_條件式_套用。

例如,若要在 hover 時套用 bg-sky-700 類別,請使用 hover:bg-sky-700 類別:

將滑鼠移到這個按鈕上,查看背景顏色變化

<button class="bg-sky-500 hover:bg-sky-700 ...">Save changes</button>
這與傳統 CSS 有何不同?

使用傳統方式撰寫 CSS 時,同一個類別名稱會根據當前狀態執行不同的操作:

傳統上,同一個類別名稱會在 hover 時套用不同樣式

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

在 Tailwind 中,不是將 hover 狀態的樣式加到現有類別,而是為元素添加另一個_僅_在 hover 時執行操作的類別:

在 Tailwind 中,預設狀態和 hover 狀態使用不同的類別

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

注意 hover:bg-sky-700 _僅_定義 :hover 狀態的樣式嗎?它預設不做任何事,但只要將滑鼠移到帶有該類別的元素上,背景顏色就會變成 sky-700

這就是我們說通用類別可以_條件式_套用的意思——透過使用變體,你可以精確控制設計在不同狀態下的行為,而無需離開 HTML。

Tailwind 包含了幾乎所有你需要的變體,包括:

這些變體甚至可以堆疊使用,以針對更具體的情況,例如在深色模式、中等斷點、hover 時改變背景顏色:

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

在本指南中,你將了解框架中所有可用的變體、如何將它們與自訂類別一起使用,甚至如何建立自己的變體。

偽類別(Pseudo-classes)

:hover、:focus 和 :active

使用 hoverfocusactive 變體在 hover、focus 和 active 狀態下設定元素樣式:

嘗試與這個按鈕互動,查看 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、:odd 和 :even

使用 firstlast 變體在元素是第一個子元素或最後一個子元素時設定樣式:

<ul role="list">  {#each people as person}    <!-- Remove top/bottom padding when first/last child -->    <li class="flex py-4 first:pt-0 last:pb-0">      <img class="h-10 w-10 rounded-full" src={person.imageUrl} alt="" />      <div class="ml-3 overflow-hidden">        <p class="text-sm font-medium text-gray-900 dark:text-white">{person.name}</p>        <p class="truncate text-sm text-gray-500 dark:text-gray-400">{person.email}</p>      </div>    </li>  {/each}</ul>

你也可以使用 oddeven 變體在元素是奇數或偶數子元素時設定樣式:

NameTitleEmail
Jane CooperRegional Paradigm Technician[email protected]
Cody FisherProduct Directives Officer[email protected]
Leonard KrasnerSenior Designer[email protected]
Emily SelmanVP, Hardware Engineering[email protected]
Anna RobertsChief Strategy Officer[email protected]
<table>  <!-- ... -->  <tbody>    {#each people as person}      <!-- Use different background colors for odd and even rows -->      <tr class="odd:bg-white even:bg-gray-50 dark:odd:bg-gray-900/50 dark:even:bg-gray-950">        <td>{person.name}</td>        <td>{person.title}</td>        <td>{person.email}</td>      </tr>    {/each}  </tbody></table>

使用 nth-*nth-last-* 變體根據子元素在列表中的位置設定樣式:

<div class="nth-3:underline">  <!-- ... --></div><div class="nth-last-5:underline">  <!-- ... --></div><div class="nth-of-type-4:underline">  <!-- ... --></div><div class="nth-last-of-type-6:underline">  <!-- ... --></div>

預設情況下你可以傳入任何數字,並使用任意值來建立更複雜的表達式,如 nth-[2n+1_of_li]

Tailwind 還包含其他結構性偽類別的變體,如 :only-child:first-of-type:empty 等。

請參閱偽類別參考以獲取完整的可用偽類別變體清單。

:required 和 :disabled

使用 requiredinvaliddisabled 等變體在不同狀態下設定表單元素樣式:

嘗試輸入有效的電子郵件地址來查看樣式變化

<input  type="text"  value="tbone"  disabled  class="invalid:border-pink-500 invalid:text-pink-600 focus:border-sky-500 focus:outline focus:outline-sky-500 focus:invalid:border-pink-500 focus:invalid:outline-pink-500 disabled:border-gray-200 disabled:bg-gray-50 disabled:text-gray-500 disabled:shadow-none dark:disabled:border-gray-700 dark:disabled:bg-gray-800/20 ..."/>

使用變體處理這類情況可以減少模板中的條件邏輯,讓你無論輸入處於什麼狀態都能使用相同的類別集合,並讓瀏覽器為你套用正確的樣式。

Tailwind 還包含其他表單狀態的變體,如 :read-only:indeterminate:checked 等。

請參閱偽類別參考以獲取完整的可用偽類別變體清單。

:has()

使用 has-* 變體根據其後代元素的狀態或內容來設定元素樣式:

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

你可以將 has-* 與偽類別一起使用,如 has-[:focus],根據後代元素的狀態來設定元素樣式。你也可以使用元素選擇器,如 has-[img]has-[a],根據後代元素的內容來設定元素樣式。

根據群組的後代元素設定樣式(Styling based on the descendants of a group)

如果你需要根據父元素的後代元素來設定元素樣式,你可以用 group 類別標記父元素,並使用 group-has-* 變體來設定目標元素樣式:

Spencer Sharp

Product Designer at planeteria.tech

Casey Jordan

Just happy to be here.

Alex Reed

A multidisciplinary designer, working at the intersection of art and technology.

alex-reed.com

Taylor Bailey

Pushing pixels. Slinging divs.

<div class="group ...">  <img src="..." />  <h4>Spencer Sharp</h4>  <svg class="hidden group-has-[a]:block ..."><!-- ... --></svg>  <p>Product Designer at <a href="...">planeteria.tech</a></p></div>

根據同層元素的後代設定樣式(Styling based on the descendants of a peer)

如果你需要根據同層元素的後代元素來設定元素樣式,你可以用 peer 類別標記同層元素,並使用 peer-has-* 變體來設定目標元素樣式:

Today
<div>  <label class="peer ...">    <input type="checkbox" name="todo[1]" checked />    Create a to do list  </label>  <svg class="peer-has-checked:hidden ..."><!-- ... --></svg></div>

:not()

使用 not- 變體在條件不成立時設定元素樣式。

當與其他偽類別變體結合時特別強大,例如將 not-focus:hover: 結合,僅在元素未獲得焦點時套用 hover 樣式:

嘗試讓按鈕獲得焦點,然後將滑鼠移到上面

<button class="bg-indigo-600 hover:not-focus:bg-indigo-700">  <!-- ... --></button>

你也可以將 not- 變體與媒體查詢變體(如 forced-colorssupports)結合,僅在使用者環境的某些條件不成立時設定元素樣式:

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

根據父元素狀態設定樣式(Styling based on parent state)

當你需要根據某個_父_元素的狀態來設定元素樣式時,用 group 類別標記父元素,並使用 group-* 變體(如 group-hover)來設定目標元素樣式:

將滑鼠移到卡片上,查看兩個文字元素的顏色變化

<a href="#" class="group ...">  <div>    <svg class="stroke-sky-500 group-hover:stroke-white ..." fill="none" viewBox="0 0 24 24">      <!-- ... -->    </svg>    <h3 class="text-gray-900 group-hover:text-white ...">New project</h3>  </div>  <p class="text-gray-500 group-hover:text-white ...">Create a new project from a variety of starting templates.</p></a>

這個模式適用於每個偽類別變體,例如 group-focusgroup-active,甚至 group-odd

區分巢狀群組(Differentiating nested groups)

當使用巢狀群組時,你可以透過使用 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。

任意群組(Arbitrary groups)

你可以透過在方括號中提供自訂選擇器作為任意值來即時建立一次性的 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>

隱式群組(Implicit groups)

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

根據同層元素狀態設定樣式(Styling based on sibling state)

當你需要根據_同層_元素的狀態來設定元素樣式時,用 peer 類別標記同層元素,並使用 peer-* 變體(如 peer-invalid)來設定目標元素樣式:

嘗試輸入有效的電子郵件地址來查看警告消失

<form>  <label class="block">    <span class="...">Email</span>    <input type="email" class="peer ..." />    <p class="invisible peer-invalid:visible ...">Please provide a valid email address.</p>  </label></form>

這讓各種巧妙的技巧成為可能,例如浮動標籤,完全不需要 JS。

這個模式適用於每個偽類別變體,例如 peer-focuspeer-requiredpeer-disabled

需要注意的是,由於 CSS 中後續同層組合器的運作方式,peer 標記只能用於_前面的_同層元素:

這不會生效,只有前面的同層元素可以被標記為 peer

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

區分 peers(Differentiating peers)

當使用多個 peer 時,你可以透過使用 peer/{name} 類別為 peer 指定唯一名稱,並在變體中使用 peer-checked/{name} 等類別來包含該名稱,從而根據_特定_ peer 的狀態來設定樣式:

Published status
<fieldset>  <legend>Published status</legend>  <input id="draft" class="peer/draft" type="radio" name="status" checked />  <label for="draft" class="peer-checked/draft:text-sky-500">Draft</label>  <input id="published" class="peer/published" type="radio" name="status" />  <label for="published" class="peer-checked/published:text-sky-500">Published</label>  <div class="hidden peer-checked/draft:block">Drafts are only visible to administrators.</div>  <div class="hidden peer-checked/published:block">Your post will be publicly visible on your site.</div></fieldset>

Peer 可以隨意命名,無需任何設定——只需直接在標記中命名你的 peer,Tailwind 就會自動產生必要的 CSS。

任意 peers(Arbitrary peers)

你可以透過在方括號中提供自訂選擇器作為任意值來即時建立一次性的 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>

偽元素(Pseudo-elements)

::before 和 ::after

使用 beforeafter 變體設定 ::before::after 偽元素樣式:

<label>  <span class="text-gray-700 after:ml-0.5 after:text-red-500 after:content-['*'] ...">Email</span>  <input type="email" name="email" class="..." placeholder="[email protected]" /></label>

使用這些變體時,Tailwind 會預設自動添加 content: '',所以除非你想要不同的值,否則不需要指定它:

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

值得注意的是,在 Tailwind 專案中,大多數情況下你並不真正需要 ::before::after 偽元素——通常使用真正的 HTML 元素會更簡單。

例如,以下是上面相同的設計,但使用 <span> 而不是 ::before 偽元素,這樣更容易閱讀,實際上程式碼也更少:

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

beforeafter 保留給那些偽元素的內容不應該實際存在於 DOM 中、且不能被使用者選取的情況。

::placeholder

使用 placeholder 變體設定任何 input 或 textarea 的佔位文字樣式:

<input  class="placeholder:text-gray-500 placeholder:italic ..."  placeholder="Search for anything..."  type="text"  name="search"/>

::file

使用 file 變體設定檔案輸入中的按鈕樣式:

Current profile photo
<input  type="file"  class="file:mr-4 file:rounded-full file:border-0 file:bg-violet-50 file:px-4 file:py-2 file:text-sm file:font-semibold file:text-violet-700 hover:file:bg-violet-100 dark:file:bg-violet-600 dark:file:text-violet-100 dark:hover:file:bg-violet-500 ..."/>

::marker

使用 marker 變體設定列表中的計數器或項目符號樣式:

Ingredients

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

我們將 marker 變體設計為可繼承的,所以雖然你可以直接在 <li> 元素上使用它,但也可以在父元素上使用以避免重複。

::selection

使用 selection 變體設定活動文字選取的樣式:

嘗試用滑鼠選取一些文字

So I started to walk into the water. I won't lie to you boys, I was terrified. But I pressed on, and as I made my way past the breakers a strange calm came over me. I don't know if it was divine intervention or the kinship of all living things but I tell you Jerry at that moment, I was a marine biologist.

<div class="selection:bg-fuchsia-300 selection:text-fuchsia-900">  <p>    So I started to walk into the water. I won't lie to you boys, I was terrified. But I pressed on, and as I made my    way past the breakers a strange calm came over me. I don't know if it was divine intervention or the kinship of all    living things but I tell you Jerry at that moment, I <em>was</em> a marine biologist.  </p></div>

我們將 selection 變體設計為可繼承的,所以你可以在樹狀結構的任何位置添加它,它將被套用到所有後代元素。

這讓你可以輕鬆地在整個網站中設定與品牌相符的選取顏色:

<html>  <head>    <!-- ... -->  </head>  <body class="selection:bg-pink-300">    <!-- ... -->  </body></html>

::first-line 和 ::first-letter

使用 first-line 變體設定內容區塊中第一行的樣式,使用 first-letter 變體設定第一個字母的樣式:

Well, let me tell you something, funny boy. Y'know that little stamp, the one that says "New York Public Library"? Well that may not mean anything to you, but that means a lot to me. One whole hell of a lot.

Sure, go ahead, laugh if you want to. I've seen your type before: Flashy, making the scene, flaunting convention. Yeah, I know what you're thinking. What's this guy making such a big stink about old library books? Well, let me give you a hint, junior.

<div class="text-gray-700">  <p    class="first-letter:float-left first-letter:mr-3 first-letter:text-7xl first-letter:font-bold first-letter:text-gray-900 first-line:tracking-widest first-line:uppercase"  >    Well, let me tell you something, funny boy. Y'know that little stamp, the one that says "New York Public Library"?  </p>  <p class="mt-6">Well that may not mean anything to you, but that means a lot to me. One whole hell of a lot.</p></div>

::backdrop

使用 backdrop 變體設定原生 <dialog> 元素的背景幕樣式:

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

如果你在專案中使用原生 <dialog> 元素,你可能還想了解如何使用 open 變體來設定開啟/關閉狀態的樣式

媒體與功能查詢(Media and feature queries)

響應式斷點(Responsive breakpoints)

若要在特定斷點設定元素樣式,請使用 mdlg 等響應式變體。

例如,這將在行動裝置上呈現 3 欄格線、在中等寬度螢幕上呈現 4 欄格線、在大型寬度螢幕上呈現 6 欄格線:

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

若要根據父元素的寬度而不是視窗來設定元素樣式,請使用 @md@lg 等變體:

<div class="@container">  <div class="flex flex-col @md:flex-row">    <!-- ... -->  </div></div>

請查看響應式設計文件,深入了解這些功能的運作方式。

prefers-color-scheme

prefers-color-scheme 媒體查詢告訴你使用者偏好淺色主題還是深色主題,通常在作業系統層級設定。

使用沒有變體的通用類別來針對淺色模式,並使用 dark 變體為深色模式提供覆寫:

Light mode

Writes upside-down

The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.

Dark mode

Writes upside-down

The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.

<div class="bg-white dark:bg-gray-900 ...">  <!-- ... -->  <h3 class="text-gray-900 dark:text-white ...">Writes upside-down</h3>  <p class="text-gray-500 dark:text-gray-400 ...">    The Zero Gravity Pen can be used to write in any orientation, including upside-down. It even works in outer space.  </p></div>

請查看深色模式文件,深入了解此功能的運作方式。

prefers-reduced-motion

prefers-reduced-motion 媒體查詢告訴你使用者是否要求減少非必要的動態效果。

使用 motion-reduce 變體在使用者要求減少動態效果時條件式添加樣式:

嘗試在開發者工具中模擬 `prefers-reduced-motion: reduce` 來隱藏載入動畫

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

Tailwind 還包含一個 motion-safe 變體,僅在使用者_沒有_要求減少動態效果時添加樣式。當使用 motion-reduce 輔助類別意味著必須「取消」大量樣式時,這會很有用:

<!-- Using `motion-reduce` can mean lots of "undoing" styles --><button class="transition hover:-translate-y-0.5 motion-reduce:transition-none motion-reduce:hover:translate-y-0 ...">  Save changes</button><!-- Using `motion-safe` is less code in these situations --><button class="motion-safe:transition motion-safe:hover:-translate-x-0.5 ...">Save changes</button>

prefers-contrast

prefers-contrast 媒體查詢告訴你使用者是否要求更多或更少的對比度。

使用 contrast-more 變體在使用者要求更多對比度時條件式添加樣式:

嘗試在開發者工具中模擬 `prefers-contrast: more` 來查看變化

We need this to steal your identity.

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

Tailwind 還包含一個 contrast-less 變體,你可以用它在使用者要求較少對比度時條件式添加樣式。

forced-colors

forced-colors 媒體查詢表示使用者是否正在使用強制色彩模式。這些模式會用使用者定義的調色板覆寫你網站的文字、背景、連結和按鈕顏色。

使用 forced-colors 變體在使用者啟用強制色彩模式時條件式添加樣式:

嘗試在開發者工具中模擬 `forced-colors: active` 來查看變化

Choose a theme:
<label>  <input type="radio" class="appearance-none forced-colors:appearance-auto" />  <p class="hidden forced-colors:block">Cyan</p>  <div class="bg-cyan-200 forced-colors:hidden ..."></div>  <div class="bg-cyan-500 forced-colors:hidden ..."></div></label>

使用 not-forced-colors 變體在使用者_沒有_使用強制色彩模式時套用樣式:

<div class="not-forced-colors:appearance-none ...">  <!-- ... --></div>

Tailwind 還包含 forced color adjust 通用類別,用於選擇加入或退出強制色彩。

inverted-colors

使用 inverted-colors 變體在使用者啟用反轉色彩配置時條件式添加樣式:

<div class="shadow-xl inverted-colors:shadow-none ...">  <!-- ... --></div>

pointer 和 any-pointer

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-fineany-pointer-coarse 變體,在至少一個連接的指向裝置符合條件時提供不同的樣式。

你可以使用 pointer-noneany-pointer-none 來針對沒有指向裝置的情況。

orientation

使用 portraitlandscape 變體在視窗處於特定方向時條件式添加樣式:

<div>  <div class="portrait:hidden">    <!-- ... -->  </div>  <div class="landscape:hidden">    <p>This experience is designed to be viewed in landscape. Please rotate your device to view the site.</p>  </div></div>

scripting

使用 noscript 變體根據使用者是否啟用指令碼(如 JavaScript)來條件式添加樣式:

<div class="hidden noscript:block">  <p>This experience requires JavaScript to function. Please enable JavaScript in your browser settings.</p></div>

print

使用 print 變體條件式添加僅在列印文件時套用的樣式:

<div>  <article class="print:hidden">    <h1>My Secret Pizza Recipe</h1>    <p>This recipe is a secret, and must not be shared with anyone</p>    <!-- ... -->  </article>  <div class="hidden print:block">Are you seriously trying to print this? It's secret!</div></div>

@supports

使用 supports-[...] 變體根據使用者瀏覽器是否支援某項功能來設定樣式:

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

在底層,supports-[...] 變體會產生 @supports 規則,並接受你在方括號中使用 @supports (...) 的任何內容,如屬性/值配對,甚至使用 andor 的表達式。

為了簡潔,如果你只需要檢查是否支援某個屬性(而不是特定值),你可以只指定屬性名稱:

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

使用 not-supports-[...] 變體根據使用者瀏覽器是否不支援某項功能來設定樣式:

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

你可以透過在 supports-* 命名空間中建立新的變體,為專案中常用的 @supports 規則設定捷徑:

@custom-variant supports-grid {  @supports (display: grid) {    @slot;  }}

然後你可以在專案中使用這些自訂的 supports-* 變體:

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

@starting-style

使用 starting 變體設定元素首次在 DOM 中渲染時,或從 display: none 轉換為可見時的外觀:

<div>  <button popovertarget="my-popover">Check for updates</button>  <div popover id="my-popover" class="opacity-0 starting:open:opacity-0 ...">    <!-- ... -->  </div></div>

屬性選擇器(Attribute selectors)

ARIA 狀態(ARIA states)

使用 aria-* 變體根據 ARIA 屬性來條件式設定樣式。

例如,當 aria-checked 屬性設定為 true 時套用 bg-sky-700 類別,請使用 aria-checked:bg-sky-700 類別:

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

預設情況下,我們已包含最常見的布林 ARIA 屬性的變體:

VariantCSS
aria-busy&[aria-busy="true"]
aria-checked&[aria-checked="true"]
aria-disabled&[aria-disabled="true"]
aria-expanded&[aria-expanded="true"]
aria-hidden&[aria-hidden="true"]
aria-pressed&[aria-pressed="true"]
aria-readonly&[aria-readonly="true"]
aria-required&[aria-required="true"]
aria-selected&[aria-selected="true"]

你可以透過建立新的變體來自訂可用的 aria-* 變體:

@custom-variant aria-asc (&[aria-sort="ascending"]);@custom-variant aria-desc (&[aria-sort="descending"]);

如果你需要使用一次性的 aria 變體(不值得納入專案中),或者需要處理接受特定值的更複雜 ARIA 屬性,請使用方括號以任意值即時產生屬性:

Invoice #ClientAmount
#100Pendant Publishing$2,000.00
#101Kruger Industrial Smoothing$545.00
#102J. Peterman$10,000.25
<table>  <thead>    <tr>      <th        aria-sort="ascending"        class="aria-[sort=ascending]:bg-[url('/img/down-arrow.svg')] aria-[sort=descending]:bg-[url('/img/up-arrow.svg')]"      >        Invoice #      </th>      <!-- ... -->    </tr>  </thead>  <!-- ... --></table>

ARIA 狀態變體也可以使用 group-aria-*peer-aria-* 變體來針對父元素和同層元素:

<table>  <thead>    <tr>    <th aria-sort="ascending" class="group">      Invoice #      <svg class="group-aria-[sort=ascending]:rotate-0 group-aria-[sort=descending]:rotate-180"><!-- ... --></svg>    </th>    <!-- ... -->    </tr>  </thead>  <!-- ... --></table>

Data 屬性(Data attributes)

使用 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 屬性設定捷徑:

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

然後你可以在專案中使用這些自訂的 data-* 變體:

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

RTL 支援(RTL support)

建構多方向布局時,使用 rtlltr 變體分別在從右到左和從左到右模式下條件式添加樣式:

Left-to-right

Tom Cook

Director of Operations

Right-to-left

تامر كرم

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

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

請記住,這些變體只有在你建構需要同時支援從左到右_和_從右到左布局的網站時才有用。如果你的網站只需要支援單一方向,你不需要這些變體——只需套用對你的內容有意義的樣式即可。

開啟/關閉狀態(Open/closed state)

使用 open 變體在 <details><dialog> 元素處於開啟狀態時條件式添加樣式:

嘗試切換展開元件來查看樣式變化

Why do they call it Ovaltine?

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

<details class="border border-transparent open:border-black/10 open:bg-gray-100 ..." open>  <summary class="text-sm leading-6 font-semibold text-gray-900 select-none">Why do they call it Ovaltine?</summary>  <div class="mt-3 text-sm leading-6 text-gray-600">    <p>The mug is round. The jar is round. They should call it Roundtine.</p>  </div></details>

此變體也針對 popover 的 :popover-open 偽類別:

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

設定 inert 元素樣式(Styling inert elements)

inert 變體讓你為標記有 inert 屬性的元素設定樣式:

Notification preferences

Get notified when someones posts a comment on a post.

Get notified when someones mentions you.

<form>  <legend>Notification preferences</legend>  <fieldset>    <input type="radio" />    <label> Custom </label>    <fieldset inert class="inert:opacity-50">      <!-- ... -->    </fieldset>    <input type="radio" />    <label> Everything </label>  </fieldset></form>

這對於添加視覺提示很有用,可以清楚地表明內容區塊不具互動性。

子元素選擇器(Child selectors)

設定直接子元素樣式(Styling direct children)

雖然通常最好將通用類別直接放在子元素上,但在你需要設定無法控制的直接子元素樣式時,可以使用 * 變體:

Categories

Sales
Marketing
SEO
Analytics
Design
Strategy
Security
Growth
Mobile
UX/UI
<div>  <h2>Categories<h2>  <ul class="*:rounded-full *:border *:border-sky-100 *:bg-sky-50 *:px-2 *:py-0.5 dark:text-sky-300 dark:*:border-sky-500/15 dark:*:bg-sky-500/10 ...">    <li>Sales</li>    <li>Marketing</li>    <li>SEO</li>    <!-- ... -->  </ul></div>

需要注意的是,直接在子元素上使用通用類別覆寫樣式不會生效,因為子元素規則在一般規則之後產生,且它們具有相同的優先級:

這不會生效,子元素無法覆寫父元素給予的樣式。

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

設定所有後代元素樣式(Styling all descendants)

* 類似,** 變體可用於設定元素的子元素樣式。主要區別在於 ** 會將樣式套用到_所有_後代元素,而不僅僅是直接子元素。當你將它與其他變體結合以縮小選擇範圍時特別有用:

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

自訂變體(Custom variants)

使用任意變體(Using arbitrary variants)

就像任意值讓你可以在通用類別中使用自訂值一樣,任意變體讓你可以直接在 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 自訂變體時,& 佔位符不是必需的,就像使用預處理器巢狀時一樣。

註冊自訂變體(Registering a custom variant)

如果你發現自己在專案中多次使用相同的任意變體,可能值得使用 @custom-variant 指令建立自訂變體:

@custom-variant theme-midnight (&:where([data-theme="midnight"] *));

現在你可以在 HTML 中使用 theme-midnight:<通用類別> 變體:

<html data-theme="midnight">  <button class="theme-midnight:bg-black ..."></button></html>

添加自訂變體文件中了解更多關於添加自訂變體的資訊。

附錄(Appendix)

快速參考(Quick reference)

Tailwind 預設包含的所有變體的快速參考表。

VariantCSS
hover@media (hover: hover) { &:hover }
focus&:focus
focus-within&:focus-within
focus-visible&:focus-visible
active&:active
visited&:visited
target&:target
*:is(& > *)
**:is(& *)
has-[...]&:has(...)
group-[...]&:is(:where(.group)... *)
peer-[...]&:is(:where(.peer)... ~ *)
in-[...]:where(...) &
not-[...]&:not(...)
inert&:is([inert], [inert] *)
first&:first-child
last&:last-child
only&:only-child
odd&:nth-child(odd)
even&:nth-child(even)
first-of-type&:first-of-type
last-of-type&:last-of-type
only-of-type&:only-of-type
nth-[...]&:nth-child(...)
nth-last-[...]&:nth-last-child(...)
nth-of-type-[...]&:nth-of-type(...)
nth-last-of-type-[...]&:nth-last-of-type(...)
empty&:empty
disabled&:disabled
enabled&:enabled
checked&:checked
indeterminate&:indeterminate
default&:default
optional&:optional
required&:required
valid&:valid
invalid&:invalid
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)
print@media print
supports-[]@supports ()
aria-busy&[aria-busy="true"]
aria-checked&[aria-checked="true"]
aria-disabled&[aria-disabled="true"]
aria-expanded&[aria-expanded="true"]
aria-hidden&[aria-hidden="true"]
aria-pressed&[aria-pressed="true"]
aria-readonly&[aria-readonly="true"]
aria-required&[aria-required="true"]
aria-selected&[aria-selected="true"]
aria-[]&[aria-]
data-[]&[data-]
rtl&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *)
ltr&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *)
open&:is([open], :popover-open, :open)
starting@starting-style

偽類別參考(Pseudo-class reference)

這是 Tailwind 內含所有偽類別變體的完整範例清單,作為本指南開頭偽類別文件的補充。

:hover

使用 hover 變體在使用者將滑鼠游標懸停在元素上時設定樣式:

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

:focus

使用 focus 變體在元素獲得焦點時設定樣式:

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

:focus-within

使用 focus-within 變體在元素本身或其子元素之一獲得焦點時設定樣式:

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

:focus-visible

使用 focus-visible 變體在元素透過鍵盤獲得焦點時設定樣式:

<button class="focus-visible:outline-2 ...">Submit</button>

:active

使用 active 變體在元素被按下時設定樣式:

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

:visited

使用 visited 變體在連結已被訪問過時設定樣式:

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

:target

使用 target 變體在元素的 ID 與當前 URL 片段匹配時設定樣式:

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

:first-child

使用 first 變體在元素是第一個子元素時設定樣式:

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

:last-child

使用 last 變體在元素是最後一個子元素時設定樣式:

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

:only-child

使用 only 變體在元素是唯一子元素時設定樣式:

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

:nth-child(odd)

使用 odd 變體在元素是奇數位子元素時設定樣式:

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

:nth-child(even)

使用 even 變體在元素是偶數位子元素時設定樣式:

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

:first-of-type

使用 first-of-type 變體在元素是同類型中的第一個子元素時設定樣式:

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

:last-of-type

使用 last-of-type 變體在元素是同類型中的最後一個子元素時設定樣式:

<nav>  <img src="/logo.svg" alt="Vandelay Industries" />  {#each links as link}    <a href="#" class="mr-2 last-of-type:mr-6 ...">      <!-- ... -->    </a>  {/each}  <button>More</button></nav>

:only-of-type

使用 only-of-type 變體在元素是同類型中的唯一子元素時設定樣式:

<nav>  <img src="/logo.svg" alt="Vandelay Industries" />  {#each links as link}    <a href="#" class="mx-2 only-of-type:mx-6 ...">      <!-- ... -->    </a>  {/each}  <button>More</button></nav>

:nth-child()

使用 nth 變體在元素位於特定位置時設定樣式:

<nav>  <img src="/logo.svg" alt="Vandelay Industries" />  {#each links as link}    <a href="#" class="mx-2 nth-3:mx-6 nth-[3n+1]:mx-7 ...">      <!-- ... -->    </a>  {/each}  <button>More</button></nav>

:nth-last-child()

使用 nth-last 變體在元素從末端算起位於特定位置時設定樣式:

<nav>  <img src="/logo.svg" alt="Vandelay Industries" />  {#each links as link}    <a href="#" class="mx-2 nth-last-3:mx-6 nth-last-[3n+1]:mx-7 ...">      <!-- ... -->    </a>  {/each}  <button>More</button></nav>

:nth-of-type()

使用 nth-of-type 變體在同類型元素中位於特定位置時設定樣式:

<nav>  <img src="/logo.svg" alt="Vandelay Industries" />  {#each links as link}    <a href="#" class="mx-2 nth-of-type-3:mx-6 nth-of-type-[3n+1]:mx-7 ...">      <!-- ... -->    </a>  {/each}  <button>More</button></nav>

:nth-last-of-type()

使用 nth-last-of-type 變體在同類型元素中從末端算起位於特定位置時設定樣式:

<nav>  <img src="/logo.svg" alt="Vandelay Industries" />  {#each links as link}    <a href="#" class="mx-2 nth-last-of-type-3:mx-6 nth-last-of-type-[3n+1]:mx-7 ...">      <!-- ... -->    </a>  {/each}  <button>More</button></nav>

:empty

使用 empty 變體在元素沒有內容時設定樣式:

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

:disabled

使用 disabled 變體在輸入欄位被停用時設定樣式:

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

:enabled

使用 enabled 變體在輸入欄位啟用時設定樣式,當你只想在元素未被停用時套用另一種樣式時最有用:

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

:checked

使用 checked 變體在核取方塊或單選按鈕被勾選時設定樣式:

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

:indeterminate

使用 indeterminate 變體在核取方塊或單選按鈕處於不確定狀態時設定樣式:

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

:default

使用 default 變體在選項、核取方塊或單選按鈕是頁面初始載入時的預設值時設定樣式:

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

:optional

使用 optional 變體在輸入欄位為選填時設定樣式:

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

:required

使用 required 變體在輸入欄位為必填時設定樣式:

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

:valid

使用 valid 變體在輸入欄位驗證通過時設定樣式:

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

:invalid

使用 invalid 變體在輸入欄位驗證失敗時設定樣式:

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

:user-valid

使用 user-valid 變體在輸入欄位驗證通過且使用者已與之互動時設定樣式:

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

:user-invalid

使用 user-invalid 變體在輸入欄位驗證失敗且使用者已與之互動時設定樣式:

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

:in-range

使用 in-range 變體在輸入欄位的值在指定範圍內時設定樣式:

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

:out-of-range

使用 out-of-range 變體在輸入欄位的值超出指定範圍時設定樣式:

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

:placeholder-shown

使用 placeholder-shown 變體在輸入欄位顯示佔位文字時設定樣式:

<input class="placeholder-shown:border-gray-500 ..." placeholder="[email protected]" />

:details-content

使用 details-content 變體設定 <details> 元素的內容樣式:

<details class="details-content:bg-gray-100 ...">  <summary>Details</summary>  This is a secret.</details>

:autofill

使用 autofill 變體在輸入欄位被瀏覽器自動填入時設定樣式:

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

:read-only

使用 read-only 變體在輸入欄位為唯讀時設定樣式:

<input class="read-only:bg-gray-100 ..." />
Copyright © 2026 Tailwind Labs Inc.·商標政策(Brand)