必须用 theme.extend 增量添加自定义项,直接修改 theme 顶层键会覆盖默认值导致基础工具类失效;颜色需分基础色、语义色、状态色三层管理;fontFamily 和 fontSize 要绑定设计系统字号阶梯并设 line-height;插件仅用于原子类,复杂逻辑应交由组件层处理。

tailwind.config.js 里 theme.extend 是主题扩展的唯一合理入口
直接改 theme 顶层键(比如 colors、fontSize)会覆盖默认值,导致 bg-blue-500、text-sm 这类基础工具类失效。必须用 theme.extend 增量添加自定义项。
常见错误现象:bg-brand-primary 能用,但 bg-blue-500 突然没了;或者 text-xs 报错“class not found”。
- 只在
theme.extend下添加新键,例如brandColors、spacingScale - 若需重命名或映射已有语义(如把
blue换成公司主色),用theme.colors.blue = '#2563eb'—— 这属于“重定义”,不是“覆盖整个 colors 对象” - 所有自定义值必须是静态对象或函数返回对象,不能是动态计算(如
process.env.NODE_ENV判断)
颜色系统要分层:基础色 + 语义色 + 状态色,三者不可混写
很多人把所有颜色一股脑塞进 theme.extend.colors,结果设计稿换色时改 17 处,还漏掉 border-brand-error 这种边缘用例。
正确分层方式:
-
基础色(palette):仅存
blue、red、gray等无业务含义的色板,数值严格对应设计系统规范(如blue: { 50: '#eff6ff', 500: '#2563eb', 900: '#1e3a8a' }) -
语义色(semantic):基于基础色派生,如
primary: colors.blue[500]、success: colors.green[600],用于bg-primary、text-success -
状态色(state):仅用于交互反馈,如
hover:primary不写死色值,而用theme.extend.hoverColors = { primary: colors.blue[700] }单独管理
fontFamily 和 fontSize 必须绑定设计系统字号阶梯,而非开发直觉
设计师给的“正文 16px / 标题 24px / 小字 12px”不能直接写成 text-base: '16px'。Tailwind 的 fontSize 是一个元组,第二项控制行高和字体粗细,默认值会被丢弃。
典型错误:只设字号没设 line-height,导致 text-lg 在不同组件中行高不一致。
- 按设计系统字号表逐条配置,例如:
base: ['1rem', { lineHeight: '1.5', fontWeight: '400' }] - 避免使用
px单位,全部用rem或em保证缩放一致性 - 若需响应式字号(如移动端缩小标题),用
theme.extend.fontSize配合screen断点,而不是在 class 里写md:text-xl冗余重复
插件(plugin)不是万能补丁,复杂逻辑该抽离就抽离
看到 “需要 hover 时同时改背景+文字+边框” 就想写个 hover-group 插件?先停一下。Tailwind 插件本质是生成 CSS 类,它无法处理条件渲染、运行时状态或组件级封装。
容易踩的坑:
- 插件里用
addUtilities注入大量组合类(如.btn-primary:hover),会导致 CSS 体积暴涨且无法 tree-shake - 试图用插件模拟 Vue/React 的
v-if或useState行为,结果发现根本没法响应数据变化 - 真正该做的:把这类逻辑下沉到组件层,用
className动态拼接,或封装成可复用的 React/Vue 组件,插件只负责提供原子类(如focus-ring)
设计系统一致性真正的难点不在配置文件多写几行,而在团队是否对「什么该配进 Tailwind、什么该交给组件逻辑」有共识。一旦开始用插件绕过这个边界,后面维护成本就不是改 config 能解决的了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











