必须用 theme.extend.colors 增量添加颜色,否则全量替换会导致内置色盘丢失、依赖色名的工具类失效;自定义色需显式声明色阶对象才能支持如 -500 后缀,且连字符色名须加单引号,JIT 模式下还需确保 content 覆盖模板路径并避免动态拼接类名。

必须用 theme.extend.colors 增量添加,否则默认色盘全丢、大量类名失效。
为什么直接写 theme.colors 会崩样式
Tailwind 的 theme.colors 是全量替换逻辑,不是合并。你写 colors: { brand: '#3b82f6' },它就只认 brand 这一个键,内置的 blue、gray、indigo 全部被丢弃。所有依赖这些色名的工具类(比如 ring-blue-500、hover:bg-indigo-600)瞬间失效。
真正安全的做法只有一条:theme.extend.colors。它和默认色盘合并后参与构建,bg-brand-500 和 bg-blue-500 可以共存。
- ✅ 正确:
extend: { colors: { 'brand-blue': '#3b82f6' } } - ❌ 错误:
colors: { 'brand-blue': '#3b82f6' }(顶层直接写) - ⚠️ 高危:
extend: { colors: { blue: '#1a56db' } }(不会覆盖默认blue,只是新增同名 key,但 JIT 编译优先读内置blue,你的配置实际被忽略)
brand-red 要支持 -500 后缀,必须手动声明色阶对象
只写 'brand-red': '#e53e3e',Tailwind 只生成 bg-brand-red 这一个类;bg-brand-red-500 会报错 “class not found”。因为 Tailwind 不为自定义色自动推导明暗梯度。
立即学习“前端免费学习笔记(深入)”;
要支持完整色阶,必须显式定义对象,且键必须是字符串('50' 不是 50),值必须是合法颜色格式:
brand-red: { '50': '#fff5f5', '500': '#e53e3e', '900': '#742a2a' }- 不用填满全部 50–900,按需选 3–5 个常用档位即可
- 连字符色名(如
'dark-blue')必须加单引号,否则解析失败或静默丢弃
JIT 模式下类名写了但没效果?先查这三件事
JIT 模式只扫描源码中「字面量出现」的类名。你配得再全,模板里没真实写过这个 class,它就不会进最终 CSS。
- 临时加一行测试:
<div class="bg-brand-red-500"></div>,确保路径被content扫到 - 检查
content是否覆盖你的模板文件:Next.js 项目要同时包含app/**/*.{js,jsx,ts,tsx}和pages/**/*.{js,jsx,ts,tsx};MDX/EJS/SSR 模板也得把对应路径加进去 - 动态拼接类名(如
className={`bg-${color}-500`})必须显式加safelist,Tailwind 不执行 JavaScript,无法推断color的可能取值
十六进制值必须带 #,且变体要手动声明完整色阶
写 brand: '#3b82f6' 只生成 bg-brand、text-brand 这类基础类;bg-brand-500 会报错——因为没声明色阶。Tailwind 不会为单值自动推导明暗梯度,这和内置 blue 的行为完全不同。
想拥有完整色阶体验,必须显式定义对象,键为字符串数字('50'、'100'…'900'),值为合法十六进制(支持 3/4/6/8 位):
brandBlue: { '100': '#dbeafe', '500': '#3b82f6', '900': '#1d4ed8' }- 如果要用 CSS 变量运行时切换主题,别在
tailwind.config.js里写var(--x)——它无法静态解析出 r/g/b 值,所有色阶、透明度、暗化逻辑都会崩
最常被忽略的是:修改配置后必须重启开发服务器,JIT 不会热重载 color 配置变更。



















