什么是设计令牌
设计令牌(Design Token)是设计系统中的最小单位,它将颜色、字体、间距、阴影等视觉属性抽象为命名变量。这些变量可以在设计工具和代码之间共享,确保设计意图在从 Figma 到生产环境的整个流程中不丢失、不扭曲。
传统的设计交付流程中,设计师标注一个按钮的背景色为 #5E6AD2,开发者直接在 CSS 中写死这个值。当品牌升级需要调整主色时,开发者需要全局搜索替换,既低效又容易遗漏。设计令牌解决了这个问题:你定义一个 --color-primary: #5E6AD2,所有使用这个变量的组件会自动同步更新。
为什么 DESIGN.md 是设计令牌的理想起点
Design Extractor 生成的 DESIGN.md 已经包含了完整的视觉规范:
- 完整的配色方案(主色、辅色、中性色、语义色)
- 字体栈和字号层级
- 间距尺度和栅格系统
- 阴影、模糊、圆角等材质属性
- 动效时长和缓动曲线
这些内容本质上就是设计令牌的"原材料"。你不需要从零开始定义令牌,只需要把 DESIGN.md 中的数值映射到标准化的命名体系中。
建立令牌层级
一个成熟的设计令牌体系通常包含三个层级:
第一层:全局令牌(Global Tokens)
这是最底层的原始值,直接对应 DESIGN.md 中的提取结果。命名应该描述"是什么",而不是"用在哪里"。
:root {
--color-indigo-500: #6366F1;
--color-indigo-600: #4F46E5;
--color-gray-900: #111827;
--color-gray-50: #F9FAFB;
--font-sans: Inter, ui-sans-serif, system-ui, -apple-system, sans-serif;
--font-serif: Georgia, "Times New Roman", serif;
--space-1: 4px;
--space-2: 8px;
--space-4: 16px;
--radius-base: 6px;
--radius-lg: 12px;
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--duration-fast: 150ms;
--easing-out: cubic-bezier(0.4, 0, 0.2, 1);
}第二层:别名令牌(Alias Tokens)
别名令牌把全局令牌映射到语义化的用途上。这一层是设计系统的"翻译层",把"indigo-500"翻译为"primary"。
:root {
--color-background: var(--color-gray-50);
--color-surface: var(--color-white);
--color-text-primary: var(--color-gray-900);
--color-text-secondary: var(--color-gray-500);
--color-brand: var(--color-indigo-500);
--color-brand-hover: var(--color-indigo-600);
}第三层:组件令牌(Component Tokens)
组件令牌把别名令牌绑定到具体的 UI 组件上。这是最靠近使用端的一层。
:root {
--button-primary-bg: var(--color-brand);
--button-primary-bg-hover: var(--color-brand-hover);
--button-primary-text: var(--color-white);
--button-primary-radius: var(--radius-base);
--button-primary-padding-x: var(--space-4);
--button-primary-padding-y: var(--space-2);
}从 DESIGN.md 自动生成令牌
手动把 DESIGN.md 中的数值转换成 CSS 变量是枯燥且容易出错的。我们可以写一个简单的小型转换脚本来自动完成这个工作。
以 Design Extractor 生成的 Color System 章节为例,它通常包含类似这样的结构:
## Color
**Primary:**
- Base: #6366F1
- 50: #EEF2FF
- 100: #E0E7FF
...一个简单的正则解析脚本可以把这些提取成 CSS 变量。更理想的做法是结合 Style Dictionary——一个由 Amazon 开源的设计令牌管理工具,它可以把同一个令牌源转换成多种平台格式:CSS 变量、SCSS、Tailwind 配置、iOS/Android 原生代码等。
与 Tailwind CSS 集成
如果你使用 Tailwind CSS,最实用的做法是把设计令牌映射到 Tailwind 的 theme.extend 配置中:
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
brand: {
DEFAULT: '#6366F1',
hover: '#4F46E5',
light: '#EEF2FF',
},
surface: '#FFFFFF',
background: '#F9FAFB',
},
fontFamily: {
sans: ['Inter', 'ui-sans-serif', 'system-ui', '-apple-system', 'sans-serif'],
serif: ['Georgia', "Times New Roman", 'serif'],
},
spacing: {
'18': '4.5rem',
'88': '22rem',
},
borderRadius: {
'4': '4px',
'6': '6px',
},
transitionDuration: {
'150': '150ms',
},
transitionTimingFunction: {
'out': 'cubic-bezier(0.4, 0, 0.2, 1)',
},
},
},
}暗色主题的令牌管理
现代 SaaS 产品几乎都支持暗色主题。使用 CSS 变量管理设计令牌让暗色主题的实现变得异常简单。你只需要为暗色模式重新定义别名令牌,而组件代码完全不需要改动:
@media (prefers-color-scheme: dark) {
:root {
--color-background: var(--color-gray-950);
--color-surface: var(--color-gray-900);
--color-text-primary: var(--color-gray-50);
--color-text-secondary: var(--color-gray-400);
}
}令牌命名约定
好的命名约定是设计令牌体系可维护的关键。我们推荐以下原则:
- 使用 kebab-case:--color-primary,而非 --colorPrimary 或 --color_primary
- 从抽象到具体:--color → --color-brand → --color-brand-hover
- 避免组件名在前:--color-primary 优于 --button-color-primary,因为颜色可能被多个组件共用
- 状态后缀统一:hover、active、focus、disabled、selected
- 尺寸后缀统一:sm、base、lg、xl(对应组件尺寸),或 1、2、4、8(对应间距倍数)
维护与迭代
设计令牌不是一次性工作,而是需要随产品迭代持续维护。我们建议:
- 版本控制:把令牌定义文件纳入 Git 管理,变更通过 PR 审核
- 文档化:使用 Storybook 或类似工具展示每个令牌的可视化效果
- 自动化检测:在 CI 中运行脚本检查代码中是否有硬编码的色值或字号,强制使用令牌
- 定期同步:当设计规范更新时,先用 Design Extractor 重新提取 DESIGN.md,然后 diff 对比令牌变化
总结
从 DESIGN.md 到设计令牌的转换,本质上是把"一次性提取"升级为"可持续使用的设计系统基础设施"。这个过程不需要复杂的工具链——从简单的 CSS 变量开始,逐步引入 Tailwind 配置、Style Dictionary,最终建立起跨越设计和开发的统一语言。
Design Extractor 帮你完成了最困难的一步:从任意网页中提取出精确的数值。接下来,你只需要给这些数值起好名字,组织好层级,就能拥有一个专业级的可维护设计系统。