Tailwind复用核心是@layer组件化、theme.extend设计令牌、插件封装逻辑,禁用运行时拼接class。需在CSS中用@layer components定义.btn-primary等原子类,在config中extend spacing/colors命名空间,并通过插件注入table-zebra等带条件样式。

用 @layer directives 组织自定义类,避免重复写 utility
直接在 HTML 里堆 bg-blue-500 text-white px-4 py-2 rounded 很快就会失控。Tailwind 不鼓励“复制粘贴 class”,而是用 @layer 把常用组合收拢到 CSS 文件里。这不是“造新 class”,而是把 utility 组合注册为可复用的原子类。
常见错误是试图用 @apply 在组件内硬塞样式,结果导致构建体积膨胀、调试困难——@apply 只应在 @layer components 或 @layer utilities 中使用,且不能包含响应式变体(如 md:bg-red-500)或状态伪类(如 hover:underline)。
- 在
src/styles.css里写:@layer components {<br> .btn-primary { @apply bg-blue-600 text-white px-4 py-2 rounded font-medium hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2; }<br>} - HTML 中直接用:
<button class="btn-primary">Submit</button> - 注意:所有
@apply中的 utility 必须已在tailwind.config.js中启用(比如ring-offset-2需确认ringOffsetWidth已配置)
用 config.theme.extend 定义设计令牌,统一控制重复值
当多个地方都用 spacing[18](即 4.5rem)做边距,或反复写 text-gray-800,说明该抽设计系统变量了。Tailwind 的 theme.extend 不是“覆盖默认值”,而是补充语义化别名,让重复值有唯一源头。
容易踩的坑是把业务色值(如 "brand-red": "#e53e3e")直接塞进 colors,结果和 red-500 冲突;正确做法是用独立命名空间,比如 brand。
立即学习“前端免费学习笔记(深入)”;
- 在
tailwind.config.js中:module.exports = {<br> theme: {<br> extend: {<br> spacing: { 'header-height': '64px' },<br> colors: { brand: { primary: '#2563eb', secondary: '#64748b' } },<br> fontFamily: { sans: ['Inter', 'system-ui'] }<br> }<br> }<br>} - 之后就能用
h-[header-height]、text-brand-primary、font-sans—— 这些不是字符串拼接,是真实生成的 utility 类 - 修改
spacing或colors后必须重启 dev server,否则新类不生效
用插件机制封装带逻辑的重复样式(比如斑马纹、禁用态)
纯 CSS 类搞不定的场景:表格行交替背景、按钮禁用时自动降级文字/背景/光标,这类需要运行时判断的逻辑,靠手写 odd:bg-gray-50 even:bg-white 或一堆 disabled:* 很脆弱。Tailwind 插件能注入带条件的 utility,且与 PurgeCSS 兼容。
典型错误是把插件写成纯 JS 函数却不返回 addUtilities,或者在插件里调用 addComponents 却没加 variants 支持响应式/状态。
- 创建
plugins/zebra.js:const plugin = require('tailwindcss/plugin')<br><br>module.exports = plugin(function({ addUtilities, variants }) {<br> addUtilities({<br> '.table-zebra tbody tr:nth-child(odd)': { backgroundColor: 'rgba(0,0,0,0.025)' },<br> '.table-zebra tbody tr:nth-child(even)': { backgroundColor: 'transparent' }<br> }, { variants: ['responsive'] })<br>}) - 在
tailwind.config.js的plugins数组中引入:require('./plugins/zebra') - HTML 中:
<table class="table-zebra">—— 不再需要每行手动加odd:/even:
别用 @apply 做“CSS-in-JS”式内联样式
看到有人在 React 组件里写 className={\`bg-\${color}-500 text-white\`},再配合 @apply 动态生成类——这违背 Tailwind 设计哲学,也破坏 PurgeCSS 的 tree-shaking。真正复用的关键是提前声明、静态绑定,而不是运行时拼接。
最常被忽略的点:PurgeCSS 默认只扫描 .html 和 .js(x) 文件里的 class 字符串。如果你把 class 名存在对象里、用模板字符串拼、或从 props 计算得出,那些类根本不会被打包进去,页面就“没样式”。
- 禁止写:
const btnClass = \`bg-\${variant}-500\`; <button className={btnClass}> - 应改为:
<button className={\`btn-\${variant}\`} />,并在@layer components中预定义.btn-primary、.btn-secondary - 如果真要动态颜色,用
style属性:style={{ backgroundColor: variantColor }},utility 类只管结构和语义
variants、没声明 @layer),样式就断在看不见的地方。


















