使用 Tailwind 功能來建立元素 (elements) 的 hover, focus 等狀態樣式。
就像是 Tailwind 在處理 響應式設計 一樣,使用合適的狀態前綴詞變化模式 (variants) 來設計元素的 hover, focus 等樣式。
<form>
<input class="border border-transparent focus:outline-none focus:ring-2 focus:ring-purple-600 focus:border-transparent ...">
<button class="bg-purple-600 hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-purple-600 focus:ring-opacity-50 ...">
Sign up
</button>
</form>
因為檔案大小的考量,並非所有的狀態變化模式都預設包含在功能中,但是我們盡了最大的努力建立出最常見的組合。
想知道全部的預設變化模式,請 參考 頁面最底部變化模式的完整列表。
如果你需要使用 Tailwind 不支援的狀態,可以參閱 建立自定義變化模式插件 來擴充所需要的變化模式。
新增 hover:
前綴詞讓元素處於 hover 狀態時才啟用該功能。
<button class="bg-red-500 hover:bg-red-700 ...">
Hover me
</button>
預設狀況下,hover
變化模式支援下列核心功能:
backgroundColor
backgroundOpacity
borderColor
borderOpacity
boxShadow
gradientColorStops
opacity
rotate
scale
skew
textColor
textDecoration
textOpacity
translate
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 hover
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
padding: ['hover'],
}
},
}
新增 focus:
前綴詞讓元素處於 focus 狀態時才啟用該功能。
<input class="focus:ring-2 focus:ring-blue-600 ...">
預設狀況下,focus
變化模式支援下列核心功能:
accessibility
backgroundColor
backgroundOpacity
borderColor
borderOpacity
boxShadow
gradientColorStops
opacity
outline
placeholderColor
placeholderOpacity
ringColor
ringOffsetColor
ringOffsetWidth
ringOpacity
ringWidth
rotate
scale
skew
textColor
textDecoration
textOpacity
translate
zIndex
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 focus
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
maxHeight: ['focus'],
}
},
}
Add the active:
prefix to only apply a utility when an element is active.
新增 active:
前綴詞讓元素處於 active 狀態時才啟用該功能。
<button class="bg-green-500 active:bg-green-700 ...">
Click me
</button>
預設狀況下,active
不支援任何核心功能。
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 active
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
backgroundColor: ['active'],
}
},
}
如果你需要在 hover 一個父元素時,讓其一個子元素產生樣式變化,在父元素加上 group
class 並且在子元素新增 group-hover:
前綴詞。
New Project
Create a new project from a variety of starting templates.
<div class="group border-indigo-500 hover:bg-white hover:shadow-lg hover:border-transparent ...">
<p class="text-indigo-600 group-hover:text-gray-900 ...">New Project</p>
<p class="text-indigo-500 group-hover:text-gray-500 ...">Create a new project from a variety of starting templates.</p>
</div>
預設狀況下,group-hover
變化模式支援下列核心功能:
backgroundColor
backgroundOpacity
borderColor
borderOpacity
boxShadow
opacity
textColor
textDecoration
textOpacity
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 group-hover
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
divideColor: ['group-hover'],
}
},
}
group-focus
變化模式的功能就像 group-hover
一樣,除了 focus:
<button class="group bg-yellow-500 focus:bg-yellow-600 ...">
<svg class="text-white group-focus:text-yellow-300 ..."></svg>
Bookmark
</button>
預設狀況下,group-focus
不支援任何核心功能。
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 group-focus
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
backgroundColor: ['group-focus'],
}
},
}
Add the focus-within:
prefix to only apply a utility when that element or any of its descendants have focus.
<form>
<div class="text-gray-400 focus-within:text-gray-600 ...">
<div class="...">
<svg fill="currentColor"></svg>
</div>
<input class="focus:ring-2 focus:ring-gray-300 ...">
</div>
</form>
預設狀況下,focus-within
變化模式支援下列核心功能:
accessibility
backgroundColor
backgroundOpacity
borderColor
borderOpacity
boxShadow
opacity
outline
ringColor
ringOffsetColor
ringOffsetWidth
ringOpacity
ringWidth
textColor
textDecoration
textOpacity
zIndex
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 focus-within
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
scale: ['focus-within'],
}
},
}
注意!目前 focus-visible 需要 JS 和 PostCSS polyfills 來提供足夠的瀏覽器支援。
新增 focus-visible:
前綴詞讓元素處於 focus 狀態且使用者使用鍵盤時才啟用該功能。
<button class="focus:ring-2 focus:ring-red-500 ...">
Ring on focus
</button>
<button class="focus:outline-none focus-visible:ring-2 focus-visible:ring-rose-500 ...">
Ring on focus-visible
</button>
請注意目前只有 Chrome、Edge 和 Firefox 支援原生的 focus-visible
功能。為了完整的瀏覽器支援,你應該要安裝設定 focus-visible JS polyfill 和 focus-visible PostCSS polyfill,並在你的 PostCSS 插件列表中於 Tailwind 之後 引用:
// postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
'postcss-focus-visible': {},
autoprefixer: {}
}
}
預設狀況下,focus-visible
不支援任何核心功能。
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 focus-visible
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
textDecoration: ['focus-visible'],
}
},
}
新增 motion-safe:
前綴詞讓 prefers-reduced-motion
符合 no-preference
時才啟用該功能。
舉例來說,這個按鈕只有在使用者沒有啟用 “Reduce motion” 時並且 hover 時才會有動畫效果。
<button class="transform motion-safe:hover:scale-110 ...">
Hover me
</button>
跟其他大部分的變化模式不一樣,motion-safe
可以結合響應式和其他變化模式,像是 hover
一起使用:
<div class="sm:motion-safe:hover:animate-spin">
<!-- ... -->
</div>
預設狀況下,motion-safe
不支援任何核心功能。
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 motion-safe
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
animation: ['motion-safe'],
}
},
}
新增 motion-reduce:
前綴詞讓 prefers-reduced-motion
符合 reduce
時才啟用該功能。
舉例來說,在預設情況下,這個按鈕在 hover 會產生動畫,但是如果使用者啟用 “Reduce motion”,則動畫就會失效。
<button class="transform hover:scale-110 motion-reduce:transform-none ...">
Hover me
</button>
跟其他大部分的變化模式不一樣,motion-reduce
可以結合響應式和其他變化模式,像是 hover
一起使用:
<div class="sm:motion-reduce:hover:animate-none">
<!-- ... -->
</div>
預設狀況下,motion-reduce
不支援任何核心功能。
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 motion-reduce
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
animation: ['motion-reduce'],
}
},
}
新增 disabled:
前綴詞讓元素處於 disabled 狀態時才啟用該功能。
<button class="disabled:opacity-50 ...">
Submit
</button>
<button class="disabled:opacity-50 ..." disabled>
Submit
</button>
預設狀況下,disabled
不支援任何核心功能。
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 disabled
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
opacity: ['disabled'],
}
},
}
新增 visited:
前綴詞讓連結為 visited 時才啟用該功能。
<a href="#" class="text-blue-600 visited:text-purple-600 ...">Link</a>
預設狀況下,visited
不支援任何核心功能。
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 visited
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
textColor: ['visited'],
}
},
}
新增 checked:
前綴詞讓 radio 或 checkbox 的狀態為 checked 時才啟用該功能。
<input type="checkbox" class="appearance-none checked:bg-blue-600 checked:border-transparent ...">
預設狀況下,checked
不支援任何核心功能。
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 checked
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
backgroundColor: ['checked'],
borderColor: ['checked'],
}
},
}
新增 first:
前綴詞使得當該元素為其父元素的第一個子元素 (first-child) 時才啟用該功能。這在元素透過某些迴圈方式產生時特別有用。
<div class="...">
<div v-for="item in items" class="transform first:rotate-45 ...">
{{ item }}
</div>
</div>
It’s important to note that you should add any first:
utilities to the child element, not the parent element.
需要注意的是,你應該要在任意的子元素上新增 first:
而不是父元素。
預設狀況下,first-child
不支援任何核心功能。
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 first
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
borderWidth: ['first'],
}
},
}
新增 last:
前綴詞使得當該元素為其父元素的最後一個子元素 (last-child) 時才啟用該功能。這在元素透過某些迴圈方式產生時特別有用。
<div class="...">
<div v-for="item in items" class="transform last:rotate-45 ...">
{{ item }}
</div>
</div>
需要注意的是,你應該要在任意的子元素上新增 last:
而不是父元素。
預設狀況下,last-child
不支援任何核心功能。
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 last
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
borderWidth: ['last'],
}
},
}
新增 odd:
前綴詞使得當該元素為其父元素的奇數子元素 (odd-child) 時才啟用該功能。這在元素透過某些迴圈方式產生時特別有用。
<div class="...">
<div v-for="item in items" class="transform odd:rotate-45 ...">
{{ item }}
</div>
</div>
It’s important to note that you should add any odd:
utilities to the child element, not the parent element.
需要注意的是,你應該要在任意的子元素上新增 odd:
而不是父元素。
預設狀況下,odd-child
不支援任何核心功能。
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 odd
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
backgroundColor: ['odd'],
}
},
}
新增 even:
前綴詞使得當該元素為其父元素的偶數子元素 (even-child) 時才啟用該功能。這在元素透過某些迴圈方式產生時特別有用。
<div class="...">
<div v-for="item in items" class="transform even:rotate-45 ...">
{{ item }}
</div>
</div>
需要注意的是,你應該要在任意的子元素上新增 even:
而不是父元素。
預設狀況下,even-child
不支援任何核心功能。
你可以在 tailwind.config.js
文件中的 variants
部分開關特定功能的 even
變化模式:
// tailwind.config.js
module.exports = {
// ...
variants: {
extend: {
backgroundColor: ['even'],
}
},
}
狀態變化模式也是響應式的,舉例來說,這代表你可以讓同一個元素依照不同的斷點使用不同的 hover 樣式。
要讓狀態變化模式在一個特定的斷點作用,需要將響應式前綴詞添加在狀態前綴詞的前面:
<button class="... hover:bg-green-500 sm:hover:bg-blue-500">
<!-- ... -->
</button>
你可以為你自定義的 CSS class 新增狀態變化模式,只要使用 @variants
指令將它們給囊括著:
/* Input: */
@variants group-hover, hover, focus {
.banana {
color: yellow;
}
}
/* Output: */
.banana {
color: yellow;
}
.group:hover .group-hover\:banana {
color: yellow;
}
.hover\:banana:hover {
color: yellow;
}
.focus\:banana:focus {
color: yellow;
}
在 @variants 指令 可以獲得更多的資訊。
你可以藉由撰寫自定義的變化模式插件建立你自己的狀態變化模式,如果 Tailwind 預設不支援的話。
舉例來說,這個簡單的插件新增 required
pseudo-class 變化模式的支援:
// tailwind.config.js
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addVariant, e }) {
addVariant('required', ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
return `.${e(`required${separator}${className}`)}:required`
})
})
})
]
}
在 新增變化模式 中可以獲得更多關於撰寫變化模式插件的資訊。
受限於檔案大小的考量,Tailwind 預設並沒有支援所有功能的變化模式。
參考 設定變化模式 來為你的專案設置啟用哪些變化模式。
// Default configuration
module.exports = {
// ...
variants: {
accessibility: ['responsive', 'focus-within', 'focus'],
alignContent: ['responsive'],
alignItems: ['responsive'],
alignSelf: ['responsive'],
animation: ['responsive'],
appearance: ['responsive'],
backdropBlur: ['responsive'],
backdropBrightness: ['responsive'],
backdropContrast: ['responsive'],
backdropFilter: ['responsive'],
backdropGrayscale: ['responsive'],
backdropHueRotate: ['responsive'],
backdropInvert: ['responsive'],
backdropOpacity: ['responsive'],
backdropSaturate: ['responsive'],
backdropSepia: ['responsive'],
backgroundAttachment: ['responsive'],
backgroundBlendMode: ['responsive'],
backgroundClip: ['responsive'],
backgroundColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
backgroundImage: ['responsive'],
backgroundOpacity: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
backgroundPosition: ['responsive'],
backgroundRepeat: ['responsive'],
backgroundSize: ['responsive'],
backgroundOrigin: ['responsive'],
blur: ['responsive'],
borderCollapse: ['responsive'],
borderColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
borderOpacity: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
borderRadius: ['responsive'],
borderStyle: ['responsive'],
borderWidth: ['responsive'],
boxDecorationBreak: ['responsive'],
boxShadow: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],
boxSizing: ['responsive'],
brightness: ['responsive'],
clear: ['responsive'],
container: ['responsive'],
contrast: ['responsive'],
cursor: ['responsive'],
display: ['responsive'],
divideColor: ['responsive', 'dark'],
divideOpacity: ['responsive', 'dark'],
divideStyle: ['responsive'],
divideWidth: ['responsive'],
dropShadow: ['responsive'],
fill: ['responsive'],
filter: ['responsive'],
flex: ['responsive'],
flexDirection: ['responsive'],
flexGrow: ['responsive'],
flexShrink: ['responsive'],
flexWrap: ['responsive'],
float: ['responsive'],
fontFamily: ['responsive'],
fontSize: ['responsive'],
fontSmoothing: ['responsive'],
fontStyle: ['responsive'],
fontVariantNumeric: ['responsive'],
fontWeight: ['responsive'],
gap: ['responsive'],
gradientColorStops: ['responsive', 'dark', 'hover', 'focus'],
grayscale: ['responsive'],
gridAutoColumns: ['responsive'],
gridAutoFlow: ['responsive'],
gridAutoRows: ['responsive'],
gridColumn: ['responsive'],
gridColumnEnd: ['responsive'],
gridColumnStart: ['responsive'],
gridRow: ['responsive'],
gridRowEnd: ['responsive'],
gridRowStart: ['responsive'],
gridTemplateColumns: ['responsive'],
gridTemplateRows: ['responsive'],
height: ['responsive'],
hueRotate: ['responsive'],
inset: ['responsive'],
invert: ['responsive'],
isolation: ['responsive'],
justifyContent: ['responsive'],
justifyItems: ['responsive'],
justifySelf: ['responsive'],
letterSpacing: ['responsive'],
lineHeight: ['responsive'],
listStylePosition: ['responsive'],
listStyleType: ['responsive'],
margin: ['responsive'],
maxHeight: ['responsive'],
maxWidth: ['responsive'],
minHeight: ['responsive'],
minWidth: ['responsive'],
mixBlendMode: ['responsive'],
objectFit: ['responsive'],
objectPosition: ['responsive'],
opacity: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],
order: ['responsive'],
outline: ['responsive', 'focus-within', 'focus'],
overflow: ['responsive'],
overscrollBehavior: ['responsive'],
padding: ['responsive'],
placeContent: ['responsive'],
placeItems: ['responsive'],
placeSelf: ['responsive'],
placeholderColor: ['responsive', 'dark', 'focus'],
placeholderOpacity: ['responsive', 'dark', 'focus'],
pointerEvents: ['responsive'],
position: ['responsive'],
resize: ['responsive'],
ringColor: ['responsive', 'dark', 'focus-within', 'focus'],
ringOffsetColor: ['responsive', 'dark', 'focus-within', 'focus'],
ringOffsetWidth: ['responsive', 'focus-within', 'focus'],
ringOpacity: ['responsive', 'dark', 'focus-within', 'focus'],
ringWidth: ['responsive', 'focus-within', 'focus'],
rotate: ['responsive', 'hover', 'focus'],
saturate: ['responsive'],
scale: ['responsive', 'hover', 'focus'],
sepia: ['responsive'],
skew: ['responsive', 'hover', 'focus'],
space: ['responsive'],
stroke: ['responsive'],
strokeWidth: ['responsive'],
tableLayout: ['responsive'],
textAlign: ['responsive'],
textColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
textDecoration: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],
textOpacity: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],
textOverflow: ['responsive'],
textTransform: ['responsive'],
transform: ['responsive'],
transformOrigin: ['responsive'],
transitionDelay: ['responsive'],
transitionDuration: ['responsive'],
transitionProperty: ['responsive'],
transitionTimingFunction: ['responsive'],
translate: ['responsive', 'hover', 'focus'],
userSelect: ['responsive'],
verticalAlign: ['responsive'],
visibility: ['responsive'],
whitespace: ['responsive'],
width: ['responsive'],
wordBreak: ['responsive'],
zIndex: ['responsive', 'focus-within', 'focus']
}
}