配置您的项目中启用哪些功能变体。
tailwind.config.js
文件中的 variants
部分是您控制每个核心插件应该启用哪些变体的地方。
// tailwind.config.js
module.exports = {
variants: {
extend: {
backgroundColor: ['active'],
// ...
borderColor: ['focus-visible', 'first'],
// ...
textColor: ['visited'],
}
},
}
每个属性都是一个核心插件名称,指向一个要为该插件生成的变体数组。
以下是支持的开箱即用的变体:
变体 | 描述 |
---|---|
responsive | Responsive variants like sm , md , lg , and xl . |
dark | Targets dark mode. |
motion-safe | Targets the prefers-reduced-motion: no-preference media query. |
motion-reduce | Targets the prefers-reduced-motion: reduce media query. |
first | Targets the first-child pseudo-class. |
last | Targets the last-child pseudo-class. |
odd | Targets the odd-child pseudo-class. |
even | Targets the even-child pseudo-class. |
visited | Targets the visited pseudo-class. |
checked | Targets the checked pseudo-class. |
group-hover | Targets an element when a marked parent matches the hover pseudo-class. |
group-focus | Targets an element when a marked parent matches the focus pseudo-class. |
focus-within | Targets the focus-within pseudo-class. |
hover | Targets the hover pseudo-class. |
focus | Targets the focus pseudo-class. |
focus-visible | Targets the focus-visible pseudo-class. |
active | Targets the active pseudo-class. |
disabled | Targets the disabled pseudo-class. |
关于变体如何工作的更多信息,请阅读我们的文档 响应式变体、深色模式变体 和 悬停、焦点和其他状态变体。
如果您想在默认值之外为插件启用额外的变体,您可以使用 extend
关键字来配置您的变体,类似于您如何在 theme
部分使用 extend。
// tailwind.config.js
module.exports = {
variants: {
// The 'active' variant will be generated in addition to the defaults
extend: {
backgroundColor: ['active']
}
},
}
因为 变体的顺序很重要,在 extend
键下添加的任何变体都会使用合理的默认变体顺序自动为您排序。如果有必要,您可以使用 variantOrder 选项自定义这个顺序。
任何直接在 variants
键下配置的变体将覆盖该插件的默认变体。
// tailwind.config.js
module.exports = {
variants: {
// Only 'active' variants will be generated
backgroundColor: ['active'],
},
}
当覆盖默认变体时,确保您总是指定所有您想启用的变体,而不仅仅是您想添加的新变体。
需要注意的是,当覆盖变体时,变体会按照您指定的顺序生成,因此列表末尾的变体将优先于列表开头的变体。
例如,在这里,focus
变体对 backgroundColor
功能类具有最高优先级,但 hover
变体对 borderColor
功能类具有最高优先级。
// tailwind.config.js
module.exports = {
variants: {
backgroundColor: ['hover', 'focus'],
borderColor: ['focus', 'hover'],
},
}
/* Generated CSS */
.bg-black { background-color: #000 }
.bg-white { background-color: #fff }
/* ... */
.hover\:bg-black:hover { background-color: #000 }
.hover\:bg-white:hover { background-color: #fff }
/* ... */
.focus\:bg-black:focus { background-color: #000 }
.focus\:bg-white:focus { background-color: #fff }
/* ... */
.border-black { border-color: #000 }
.border-white { border-color: #fff }
/* ... */
.focus\:border-black:focus { border-color: #000 }
.focus\:border-white:focus { border-color: #fff }
/* ... */
.hover\:border-black:hover { border-color: #000 }
.hover\:border-white:hover { border-color: #fff }
/* ... */
这意味着,给定以下HTML:
<input class="focus:bg-white hover:bg-black focus:border-white hover:border-black">
...如果输入框同时悬停和聚焦,背景将是白色的,但边框将是黑色的。
作为终端用户,这样按顺序生成变体能给您带来最大的灵活性,但它也是一个利器,如果您不小心,可能会产生意想不到的后果。我们建议 启用额外的变体,而不是尽可能地覆盖默认值,并且只把这个功能作为一个逃生通道。
responsive
变体在 Tailwind 中是一个特殊的情况,并且不会受到您在变体配置中列出的顺序的影响。
这是因为 responsive
变体会自动与其他变体堆叠在一起,这意味着如果您为一个功能指定了 responsive
和 hover
变体,Tailwind 也会生成 responsive hover 变体。
// tailwind.config.js
module.exports = {
variants: {
backgroundColor: ['responsive', 'hover'],
borderColor: ['responsive', 'focus'],
},
}
无论 responsive
出现在您的 variants
列表中的哪个位置,响应式变体都会被归为一组,并默认插入到您的样式表的最后,以避免特定性问题。
如果您出于任何原因想定制这种行为,您可以使用 @tailwind screens 指令来指定响应的变体应该插入的位置。
dark
、motion-safe
和 motion-reduce
变体也会与其他变体叠加,但与 responsive
不同的是,它们叠加在同一个 "slot" 中,所以您可以将它们与 responsive
和简单状态变体结合起来,但不能相互结合。
这些变体的顺序相对于他们相互之间来说很重要,但相对于其他变体来说不重要。几乎无法想象到这些变体在实践中会相互冲突的情况,所以无论如何,这最终都不是问题。
您可以在您的 variants
配置中以任何顺序包含这些变种,而且永远不会注意到区别。
您可以使用特殊的 DEFAULT
变体来控制相对于其他变体而言,一个功能的普通、无前缀的版本生成的地方。
这是一个高级特性,只有当您有一个自定义的变体(比如下面例子中的 children
),它的优先级应该比普通版本的功能低时才会真正有用。
// tailwind.config.js
module.exports = {
variants: {
backgroundColor: ['children', 'DEFAULT', 'hover', 'focus'],
},
}
/* Generated CSS */
.children\:bg-black > * { background-color: #000; }
.children\:bg-white > * { background-color: #fff; }
.bg-black { background-color: #000 }
.bg-white { background-color: #fff }
/* ... */
.hover\:bg-black:hover { background-color: #000 }
.hover\:bg-white:hover { background-color: #fff }
/* ... */
.focus\:bg-black:focus { background-color: #000 }
.focus\:bg-white:focus { background-color: #fff }
/* ... */
在 变体插件文档 中了解更多关于创建自定义变体的信息。
如果您编写或安装了一个 插件,这个插件增加了一个新的变体,您可以通过在您的变体配置中加入它来启用这个变体,就像它是一个内置变体一样。
例如,tailwindcss-interaction-variants 插件 增加了一个 group-disabled
变体(其中之一)。
// tailwind.config.js
{
variants: {
backgroundColor: ['responsive', 'hover', 'focus', 'group-disabled'],
},
plugins: [
require('tailwindcss-interaction-variants')(),
],
}
在变体插件文档 中了解更多关于创建自定义变体的信息。
如果您想为一个自定义变量指定一个默认的排序位置,覆盖您的 variantOrder
来包含自定义变体。
// tailwind.config.js
module.exports = {
// ...
variantOrder: [
'first',
'last',
'odd',
'even',
'visited',
'checked',
'group-hover',
'group-focus',
'focus-within',
'hover',
'focus',
'focus-visible',
'active',
'group-disabled', // Custom variant
'disabled',
],
variants: {
extend: {
backgroundColor: ['group-disabled'],
}
}
}
您需要在覆盖 variantOrder
时指定整个列表,以包含任何自定义变体。
这里是一个 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'],
backdropDropShadow: ['responsive'],
backdropFilter: ['responsive'],
backdropGrayscale: ['responsive'],
backdropHueRotate: ['responsive'],
backdropInvert: ['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'],
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']
}
}