设计令牌(Design Tokens):为什么它是设计系统的基础设施

设计令牌(Design Tokens)是设计系统的基础设施,本文深入讲解设计令牌的概念、语义层级、命名规范,以及如何通过Style Dictionary、Token Studio等工具实现设计到代码的自动化,并分享常见误区和落地步骤,帮助团队建设可维护的设计系统。

从一次主题化改造说起

去年帮一个中大型团队做设计系统重构,遇到一个很典型的问题:他们的组件库已经用 Less 变量统一了主色、间距和圆角,看起来一切正常。但后来业务需要支持两个品牌,每个品牌的主色、辅助色、字体都不一样。他们试着在根节点覆盖变量,结果组件样式错位,有的地方用的是品牌色,有的地方用的是基础色,还有一个地方直接硬编码了十六进制色值。整个团队花了两个迭代才理清关系。

AI technology illustration

这个问题的根源并不在于变量用没用,而在于设计决策没有被结构化管理。组件库里的 Less 变量更像是一个“存值”的地方,而不是设计语义的载体。真正能承担这个角色的,是设计令牌。

设计令牌到底是什么

设计令牌(Design Tokens)是一个带语义的键值对,比如 color.brand.primary 对应 #0066FFspace.md 对应 16px。它不只是把值抽出来,而是把“这个颜色是品牌主色”“这个间距是卡片内边距”这类设计决策固化下来。令牌是设计系统里的最小单元,也是连接设计和代码的桥梁。

一个设计系统通常包含这些类型的令牌:

  • 颜色:品牌色、中性色、功能色、文本色、边框色
  • 字体:字族、字号、字重、行高
  • 间距:留白、内边距、外边距
  • 圆角:小圆角、中圆角、大圆角
  • 阴影:层级阴影、悬浮阴影
  • 动效:时长、缓动曲线

你可能会说,这不就是 CSS 变量吗?区别在于,CSS 变量是技术实现,设计令牌是设计语义。一个设计令牌可以映射成 CSS 变量,也可以映射成 Android 的 Compose 常量或 iOS 的 UIColor,甚至导出成 Skia 的值。它的价值不在键值本身,而在它所在的层级和命名空间。

为什么说它是基础设施

基础设施的意思是,上层建筑都依赖它,但它本身不直接面向用户。设计令牌承担的是设计系统里“地基”的角色:组件库的样式基于令牌,页面布局的变量基于令牌,主题切换基于令牌,甚至设计稿里的样式也来自令牌。

拿多品牌场景来说,如果组件库里所有颜色都引用 color.brand.primary,那么切换品牌时只需要替换令牌的值,组件和页面会自动适配。但如果你在组件里直接写了 #0066FF,或者在多个地方重复定义变量,切换品牌时就只能逐个排查。这就是基础设施缺失的代价。

另一个常见场景是暗色模式。假如你的设计系统没有令牌,暗色模式下可能需要写一堆覆盖样式。而有了语义令牌,你只需要在暗色主题下重新映射 color.background.defaultcolor.text.primary 等令牌的值,组件无需改动。这也是为什么很多团队在做暗色模式时才发现令牌体系的重要性。

跨端一致更是离不开令牌。同一个设计令牌,通过工具生成 Web 的 CSS 变量、iOS 的 Swift 常量、Android 的 Kotlin 对象,可以保证三端拿到的是同一套设计决策。否则,设计走查只能靠人工比色,误差在所难免。

设计系统不可能永远不变。业务会扩展,品牌会调整,设计语言会进化。令牌体系为这些变化提供了“开关”。比如你的设计系统要支持新的无障碍规范,需要提高对比度,你只需要修改对应的语义令牌,而不必在几十个组件里找颜色。这就是基础设施的杠杆效应。

令牌的层级与命名

很多团队一开始把令牌铺平成一层,比如 bluegray-500,然后组件直接引用这些原始值。这样做在一两个主题下还能用,但一旦出现品牌差异,就会出问题。正确的做法是把令牌分成三层:

  1. 原始令牌(Primitive Tokens):对应设计稿里的基础色板、字号梯度,比如 blue-500font-size-md。它们只描述值,不带语义。
  2. 语义令牌(Semantic Tokens):描述用途,比如 color.background.defaultcolor.text.primary。它们引用原始令牌,并赋予业务含义。
  3. 组件令牌(Component Tokens):绑定到具体组件,比如 button.bg.defaultcard.radius。它们可以被组件库直接消费,同时支持组件级定制。

命名规范也很重要。我推荐采用 类型-用途-状态 的结构,例如 color.bg.hoverfont.size.body。避免用颜色名或者具体像素值做键名,因为那样会把实现细节泄漏到语义层。

工程化落地:从设计到代码的自动化

设计令牌的价值最终要靠工程化才能放大。手动维护一套 JSON,再让开发照着抄成 CSS 变量,容易同步出错。现在的主流做法是用工具从一份设计令牌源文件生成各端代码。这里以 Style Dictionary 为例。

先定义一份 tokens.json:

{
  "color": {
    "brand": {
      "primary": { "value": "#0066FF" }
    }
  },
  "space": {
    "md": { "value": "16px" }
  }
}

然后在 style-dictionary.config.js 里配置输出格式:

module.exports = {
  source: ["tokens.json"],
  platforms: {
    css: {
      transformGroup: "css",
      files: [{
        destination: "tokens.css",
        format: "css/variables"
      }]
    }
  }
}

运行 npx style-dictionary build,就会生成 tokens.css:

:root {
  --color-brand-primary: #0066FF;
  --space-md: 16px;
}

同样,你可以配置输出 Swift、Kotlin 或 SCSS 文件。这样设计侧更新一次,各端同步生成,大大减少手工维护的偏差。

除了 Style Dictionary,还有 Figma 上的 Token Studio 插件,可以直接把设计稿里的样式导出为 JSON,再接入自动化流程。整个工作流变成:设计师在 Figma 里改令牌 → 提交 JSON → CI 构建生成各端代码 → 组件库自动更新。

在实际项目中,主题切换也依赖令牌的自动化。比如你的基础令牌不变,只需要在暗色主题下覆盖语义令牌的值。生成后的 CSS 可能是这样的:

:root {
  --color-background-default: #FFFFFF;
  --color-text-primary: #1A1A1A;
}
[data-theme="dark"] {
  --color-background-default: #1A1A1A;
  --color-text-primary: #FFFFFF;
}

组件里只需要引用 var(--color-background-default),主题切换就变成切换属性值,而不是重写样式。

常见误区:令牌不是银弹

尽管设计令牌很好,但我在实际项目中见过不少失败案例,根源通常是这几个误区。

误区一:把令牌当成普通变量。有的团队把 #0066FF 定义为 --primary,然后在组件里直接使用,表面上在用令牌,实际上只是换了个变量名。一旦需要主题化,他们发现 --primary 在不同主题下语义冲突,因为缺少语义分层。

误区二:层级混乱,别名满天飞。有的团队给每个组件都建了一套令牌,结果全局有 200 个令牌,组件之间还互相引用,导致改动一个基础色,影响范围完全不可控。正确的做法是先定语义层,再让组件层收敛。

误区三:忽略设计侧的工具链。令牌如果只在代码里维护,设计稿依然用旧的色板,那么设计与开发迟早脱节。只有让设计工具直接读取同一份令牌,才能形成闭环。

误区四:过度抽象。有些团队为了“纯净”,把所有像素值都变成令牌,连一个 1px 边框也要定义 border.width.thin。这种抽象带来的成本可能超过收益。令牌应该服务于可复用的设计决策,而不是机械地替换每个数字。

误区五:令牌只在代码里维护,没有版本管理。设计令牌本质上是设计决策的数据,应该像代码一样进行版本管理。有的团队用在线文档维护,结果每次更新都靠截图和口头通知,很快文档就过期了。令牌文件应该进入 Git,有提交记录,能 diff,能回滚。

不同方案的取舍

设计令牌的落地方式没有标准答案,取决于团队规模、跨端需求和技术栈。下面是我常用来帮团队做决策的对比表:

方案 适用规模 学习成本 维护效率 跨端支持
手动维护 CSS 变量 小团队、单端
设计工具插件 + 导出 JSON 中小团队,设计开发协作密切
Style Dictionary 自动化 中大型团队、多端多品牌 较高
商业令牌管理平台 大型组织、需要权限与审计

如果你的项目只有一个 Web 端,团队不超过 5 人,手动维护 CSS 变量是可行的,但建议从一开始就引入语义层级,否则后续重构成本很高。如果团队同时维护 iOS、Android 和 Web,那 Style Dictionary 这类自动化方案几乎不可避免。

落地建议:如何让令牌真正跑起来

如果你想在现有设计系统里引入设计令牌,我的建议是不要一次性推倒重来,而是渐进式替换。具体步骤如下:

  1. 盘点现有样式:收集所有颜色、字体、间距的取值,找出重复和冲突。
  2. 建立原始令牌:从现有值里提取基础色板、字号梯度,不改变视觉表现。
  3. 定义语义令牌:与设计师一起明确每个值的用途,比如背景、文本、边框、交互状态。
  4. 选择一个小模块试点:比如先改按钮和输入框,验证令牌体系是否够用。
  5. 接入自动化工具:把令牌源文件纳入 CI,生成各端代码,替换组件库里的硬编码值。
  6. 持续演进:新功能开发时,只允许使用令牌,禁止直接写颜色值或像素值。

整个过程中,最容易被忽略的是第 3 步。很多团队直接从现有值跳到组件令牌,跳过了语义层,导致后续维护困难。语义层是设计令牌的“接口”,它定义了组件和全局值之间的解耦关系,务必认真设计。

另外,一个很容易踩的坑是:令牌在代码里跑起来了,但设计稿还在用旧的色板。解决方法是尽早接入 Token Studio 这类插件,让设计稿直接引用令牌,保证设计源与代码源一致。

最后

设计令牌不是一阵风,而是设计系统走向工程化必须要补上的基础设施。它让设计决策可以被版本管理、跨端复用、动态切换,也让设计工具与代码库有了共同语言。如果你正在建设设计系统,我建议尽早把令牌体系纳入规划,哪怕一开始很简单,也比事后补课轻松得多。

原创文章,作者:fudengji,如若转载,请注明出处:https://fudengji.cn/article/502/

(0)
上一篇 2分钟前
下一篇 2026年7月30日

相关推荐