Tailwind 的 theme 配置本身就是设计令牌的载体,所有颜色、间距、字体等值均以结构化方式定义在 tailwind.config.js 中,通过 theme.extend 组织语义化命名空间,支持多主题(如 dark: 变体 + data-theme 切换),避免绕过体系使用内联样式或 CSS 变量,确保类型安全、PurgeCSS 兼容及工具链消费。

Tailwind 的 theme 配置本身就是设计令牌的载体
Tailwind 并不提供单独的“设计令牌系统”,它的 theme 就是设计令牌的实现形式——所有颜色、间距、字体、圆角等值,本质上就是结构化的设计令牌。你不需要额外抽象一层,而是直接在 tailwind.config.js 中定义和组织它们。
关键在于把 theme.extend 当作令牌命名空间来用,而不是只塞进一堆散乱的值。比如把品牌色统一放在 colors.brand 下,而不是直接往 colors.blue 里硬编码十六进制值。
- 避免直接写
bg-[#0066cc]或text-[14px]—— 这会绕过设计令牌体系,导致不可维护 - 所有基础值(如
spacing、fontSize)应使用数组或对象形式,便于后续被插件或 JS 消费 - 如果项目需要导出令牌供 Figma 或其他工具使用,优先从
theme对象中提取,而非维护两套值
如何让设计令牌支持多主题(如暗色模式)
Tailwind 本身不管理主题切换逻辑,但它的 dark: 变体 + theme.extend.colors 结构天然适配多主题设计令牌。真正的难点在于:如何让同一组令牌(如 color.background)在不同主题下映射到不同值,且不破坏构建时的静态分析。
- 不要在 CSS 中用 JS 动态写入类名来切换主题——这会让
dark:失效,且无法被 PurgeCSS 安全识别 - 推荐做法:用
data-theme="dark"替代class="dark",并在tailwind.config.js中配置darkMode: 'class' - 在
theme.extend.colors中为每个语义色定义明/暗双值,例如:background: { DEFAULT: '#ffffff', dark: '#1a1a1a' } - 这样
bg-background在暗色模式下会自动解析为#1a1a1a,而无需重复写dark:bg-background-dark
为什么不能直接用 CSS 自定义属性(CSS variables)替代 theme
你可以用 :root { --color-primary: #0066cc; },也能配合 bg-[var(--color-primary)] 工作,但这会丢失 Tailwind 的核心优势:类型安全、自动补全、PurgeCSS 支持、以及与插件生态的兼容性。
立即学习“前端免费学习笔记(深入)”;
-
bg-[var(--color-primary)]不会被 PurgeCSS 识别,即使没用也会被打包进去 - VS Code 插件无法对
[var(--xxx)]做智能提示或跳转 - 无法参与
theme(colors.primary)这样的 JS 端消费(比如生成配色文档或动态主题预览) - 真正需要运行时动态变色(如用户选色)时,才考虑 CSS variables;静态设计系统请坚持走
theme配置路径
扩展设计令牌时最容易忽略的兼容性点
当你往 theme.extend 里加新键(比如 zIndex、transitionDuration),别忘了同步更新 corePlugins 或插件配置,否则这些值不会被生成对应工具类。
- 新增
spacing值后,mt-12这类工具类才会生效;但如果你加的是opacity,默认已启用,无需额外操作 - 自定义
fontSize必须是数组格式(含像素值和行高),否则text-lg类可能渲染异常 - 使用
@apply时,确保目标类已在theme中定义——@apply bg-brand-primary要求colors.brand.primary存在,且不能是嵌套过深的对象(如colors.brand.shades.primary会导致解析失败)
设计令牌不是越细越好,关键是保持层级扁平、命名一致、可被工具链消费。一旦开始用 theme 组织值,就别回头手写内联样式或 CSS variables——那相当于在同一个系统里混用两套令牌协议。


















