addUtilities 不支持伪类,因其仅接受扁平样式对象,键必须为合法类选择器;伪类需用 addComponents 手动嵌套或通过 addVariant 注册变体实现。

不能用 addUtilities 生成带伪类的工具类,必须改用 addComponents 或变体(variant)机制。 直接写 '.btn:hover' 这类键名会静默失败,Tailwind 不解析、不报错、也不输出 CSS。
为什么 addUtilities 不支持伪类?
addUtilities 只接受扁平样式对象,每个键必须是合法的 CSS 类选择器(如 .text-red-500),不能含 :hover、::before 等伪类或伪元素。它底层只做“类名 → 声明”映射,不处理嵌套结构。
常见错误现象:addUtilities({ '.btn:hover': { backgroundColor: 'blue' } }) 编译后完全没生成对应 CSS,控制台也无提示。
- 伪类逻辑属于组件级封装范畴,不是原子工具类职责
- Tailwind 官方明确将
:hover、:focus等归为 变体(variants),由独立系统处理 - 想让自定义类响应
hover,得靠addComponents+ 手动嵌套,或注册新变体
用 addComponents 手动写带伪类的组件类
适合封装一组有固定结构和状态的样式,比如按钮、卡片、表单项等。它允许你写完整 CSS 规则,包括伪类、媒体查询、后代选择器。
示例:注册一个带 hover/focus/active 的自定义按钮组件类
const plugin = require('tailwindcss/plugin')
module.exports = plugin(function({ addComponents, theme }) {
addComponents({
'.my-btn': {
padding: '0.5rem 1rem',
borderRadius: theme('borderRadius.md'),
backgroundColor: theme('colors.blue.500'),
color: theme('colors.white'),
'&:hover': {
backgroundColor: theme('colors.blue.600')
},
'&:focus': {
outline: '2px solid',
outlineColor: theme('colors.blue.400')
},
'&:active': {
transform: 'scale(0.98)'
}
}
})
})
- 必须显式注册到
tailwind.config.js的plugins数组中 -
&:hover写法是安全的,addComponents支持嵌套对象语法 - 注意:这类类名不会自动获得响应式前缀(如
md:my-btn),需手动加媒体查询包裹
注册新变体(如 disabled:)让工具类响应伪类
若你想让已有工具类(如 bg-red-500)也能在禁用状态下生效,就得扩展变体系统,而不是硬编码类名。
示例:添加 disabled: 变体,使 disabled:bg-gray-300 生效
const plugin = require('tailwindcss/plugin')
module.exports = plugin(function({ addVariant, e }) {
addVariant('disabled', ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
return `.${e(`disabled${separator}${className}`)}:disabled`
})
})
})
-
addVariant是注册新修饰符的唯一方式,disabled:会编译成.disabled\:bg-gray-300:disabled - 必须解构
e并用于转义分隔符(separator),否则类名含冒号时解析失败 - 这个变体对所有已有的工具类(
bg-、text-、opacity-等)都自动生效 - 别漏掉
plugins数组注册,否则整个变体逻辑不加载
最易被忽略的是:变体注册插件和组件类插件都依赖 tailwindcss/plugin 包裹,且必须出现在 plugins 数组里——漏掉任一环节,就只剩空配置和静默失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











