addUtilities 是唯一可靠方式,因 Tailwind 按需生成机制仅识别官方 API 注入的类,手写类名或裸导出对象会被静默忽略;必须用 tailwindcss/plugin 包裹函数,传入扁平对象,并设 respectDefaultVariants: true 以支持变体。

直接在 tailwind.config.js 里写 CSS 类名对象不会生效,必须用插件系统注入;否则类名根本不会出现在最终 CSS 中,HTML 里写了也白写。
为什么 addUtilities 是唯一可靠方式
Tailwind 的按需生成机制只识别通过官方 API 注入的类。手写 .text-balance 在 CSS 文件里、或裸导出对象,都会被静默忽略——不报错,也不打包进产物。
-
addUtilities是 Tailwind 唯一暴露给插件的工具类注入接口,它能正确接入响应式、深色模式、hover:等变体处理流程 - 必须用
tailwindcss/plugin包裹函数,否则addUtilities和theme()不可用,构建会失败 - 传入的对象必须是扁平结构:
'.text-balance': { 'text-wrap': 'balance' }✅;不能含&:hover或嵌套 ❌ - 如果你只是组合已有工具类(比如
btn=bg-blue-500 text-white px-4 py-2),该用@apply+@layer components,不是addUtilities
如何让自定义类支持 md:、hover: 等变体
v3.4+ 版本中,variants 选项已被弃用,硬写 { variants: ['responsive', 'hover'] } 会导致断点前缀(如 md:text-balance)完全不生成。
- 正确做法是传
{ respectDefaultVariants: true },让类自动继承 Tailwind 默认启用的变体逻辑 - 如果用了旧版配置且没升级,必须手动展开媒体查询:
'@media (min-width: 768px)': { '.md\:text-balance': { ... } }(注意冒号前双反斜杠转义) - 深色模式需显式写选择器:
'.dark .dark\:text-balance': { 'text-wrap': 'balance' } - 伪类如
focus:同样依赖respectDefaultVariants: true,否则focus:text-balance不生效
带参数的类(如 aspect-16/9)必须用 matchUtilities
硬编码所有可能值('.aspect-16/9'、'.aspect-4/3'…)既冗长又不可维护,且无法支持任意值写法(如 aspect-[21/9])。
立即学习“前端免费学习笔记(深入)”;
-
matchUtilities接收正则和映射函数,自动提取并转换参数:matchUtilities({ 'aspect': (value) => ({ aspectRatio: value }) }, { supportsVariants: true }) - 必须传
e函数处理特殊字符:[`.aspect-${e('16/9')}`]: { aspectRatio: '16/9' },否则生成非法 CSS 类名 -
supportsVariants: true是关键开关,缺了sm:aspect-16/9就不会出现 -
theme()只能读取theme.extend中已声明的路径,比如想用theme('aspectRatios.16/9'),就得先在配置里补上extend: { aspectRatios: { '16/9': '16/9' } }
插件生效的三个硬性前提缺一不可
哪怕代码全对,只要漏掉其中一项,类就彻底消失——Tailwind 不报错,只沉默跳过。
-
plugins数组里必须显式require('./plugins/text-balance.js'),路径带.js后缀,字符串路径或合并 require 都无效 -
content配置必须覆盖所有使用该类的文件,例如./src/**/*.{js,ts,jsx,tsx};如果只写了./src/App.tsx,其他文件里用的类就扫不到 - 自定义类不能放在
@layer components或@layer base里,必须走插件注入;手写 CSS 即使加了@layer utilities,也无法获得变体支持
最常被忽略的是 content 路径遗漏和 respectDefaultVariants: true 缺失——前者导致类名压根不生成,后者导致 md:、hover: 全部失效,但两者都不会给出任何提示。



















