Skip to content

Design Tokens

换一个品牌绿:是到几十个页面里逐个改硬编码,还是只改一个 Token、全产品全端一起变?Design Tokens 就是把"该用哪个绿"这条设计决策抽出来,命名成变量,作为全产品唯一的"数据源"——这是设计系统通往工程化的关键一步。

为什么需要 Token:改个品牌色要改几十处

上一节你学会了把"微信绿"存成样式,改一处全变——但这只在设计文件内生效。微信要同时跑在 iOS、安卓、Web、小程序四个端上,每个端的工具、代码、文件各自一套。老板说"换个品牌绿",你要改的不止一个样式,而是 Web 端改 CSS、iOS 改颜色文件、安卓改 XML 资源、设计稿改样式,还有十几个页面里当年直接填进去的硬编码 #07C160。整整几十处、跨工具、跨端、跨语言。样式解决了"设计文件内"的复用,解决不了"跨端、跨项目"的统一。 根子在于:这条设计决策散落在了无数地方,没有唯一的源头。

专业解法:把设计决策(颜色/间距/字号/圆角/阴影)抽出来,命名成变量 Token,作为全产品唯一的"数据源"——所有端、所有工具、所有代码都去引用它,而不是复制它的值。

什么是 Token:把设计值命名成可复用变量

Token 就是把一个设计值起一个名字、存起来。它分两层:基础 Token 存最原始的原子值(回答"值是多少"),语义 Token 存"这个值用来干嘛"(回答"用在哪")。名字本身要带语义和分类——color-brand-primary 这个名字就说明它是"品牌 + 首要",承载的是决策,不只是数值。

设计值(原料)起个名字(Token)用在哪
#07C160color-brand-primary品牌绿、按钮、图标
8pxspacing-base控件间距、卡片内边距
17pxfont-size 正文档消息标题、正文
12pxfont-xs时间、角标

基础 Token 回答"值是多少",语义 Token 回答"用在哪"。微信红 #FA5151 是基础值,但它在未读角标、删除确认、报错里都是同一个危险语义——所以抽成 color-danger,而不是散落三处。

Token 引用成体系:基础是原料,语义是菜谱

Token 引用关系图

关键澄清:Token 要有引用关系,不是一次性值。一个"卡片间距 = 中等间距 × 2"的 Token,才让整个间距体系有出处、可派生、能统一调整——改 --space-unit--spacing-card 自动跟着变。

真正的 Token 不是一堆孤立的一次性值,而是互相引用的体系——语义 Token 引用基础 Token,Token 还可以引用 Token 做运算。基础 Token = 仓库里的原料(8px#07C160),语义 Token = 菜谱("卡片间距 = 中等间距 × 2")。正是因为这种引用关系,改一个基础值,所有派生它的 Token 自动跟着变。

间距 Token 的出处:spacing-4/8/16 这类间距 Token 都源自前置点 08 的 8pt 标尺——间距按 8 的倍数取,整个界面才有统一节奏。

css
--space-unit: 8px;             /* 基础:8 是间距的基本单位 */
--color-brand: #07C160;        /* 基础:微信绿的原始值 */
--spacing-md: var(--space-unit);             /* 语义:中等间距 = 1 个基本单位 */
--spacing-card: calc(var(--spacing-md) * 2); /* 语义:卡片间距 = 中距 × 2 */
--color-bg: var(--color-brand);              /* 语义:背景绿 = 品牌绿 */

Token vs 样式:Token 是样式的"数据源"

记住一句话:Token 是样式/组件的"数据源"。样式是 Token 的落地雏形,本节把它升级成"命名 + 引用"的 Token 体系。

Token 和上一节的样式是两层东西:样式在设计工具的面板里,管"图层引用同一个设置";Token 在项目共享的配置/代码里,管"决策有名有语义、跨端统一"。谁引用谁?样式引用 Token。 你在 Penpot 里建的"微信绿"样式,背后就指向 color-brand-primary 这个 Token——改 Token,样式跟着变,用了样式的图层跟着变,一条链全联动。

样式(工具层)Token(决策源头)
在哪一层设计工具里的面板项目里共享的配置/代码
管什么图层"引用同一个设置"决策"有名有语义、跨端统一"
作用范围当前设计文件整个产品 + 多个端
谁引用谁图层引用样式样式/组件引用 Token

微信案例:把微信建模成 Token 体系

把微信首页一个"消息行"用 Token 说清楚:消息标题("前同事老张")= font-size-body + color-text;消息摘要 = font-size-caption + color-text-secondary;未读角标 = color-danger(红底)+ color-text-inverse(白字);转发卡片 = radius-card + shadow-card + spacing-card。设计师调色、开发写码,都喊同一串名字——这就是设计系统的工程化。

把微信首页抽成一组 Token——这就是你在 Penpot 里重建界面时背后的"数据源"。同一个 color-brand-primary,同时喂给按钮、图标、背景。哪天换品牌色,只改这一个 Token,全产品、全端一起变。

Token类型值 / 引用用在微信
color-brand-primary基础#07C160品牌绿、按钮、图标
color-danger语义#FA5151未读角标、删除、报错
color-text语义#1F1F1F标题、正文
color-text-secondary语义#999999时间、摘要
color-bg语义引用 color-brand-primary背景
spacing-base基础8px间距基本单位
spacing-card语义spacing-base × 2卡片内边距
font-size-body基础17px正文档
font-weight-title基础600标题档
radius-card基础12px卡片圆角
shadow-card基础柔和投影转发卡片、弹层

深度

基础 vs 语义 Token:什么时候该建哪一个

场景该建哪种例子
看到一个"原始数值"第一次出现基础 Token微信绿 #07C160
同一个值要"用在多个用途"语义 Token绿既是背景又是按钮,各建一个语义
想表达"危险/成功/警告"这种含义语义 Tokencolor-dangercolor-success
想表达"×××间距/×××字号"语义 Tokenspacing-cardfont-caption

铁律:基础只管"值干净",语义管"用在哪"。别把"用途"硬塞进基础 Token,也别把"原始值"塞进语义 Token。

反模式:Token 用错的四种坑

  1. 把 Token 当一次性值,复制粘贴:建了 spacing-card,又手写 16px。体系断了,改一处要追 N 处。
  2. 语义 Token 里塞死数值color-danger 直接写 #FA5151,不复用基础 Token。改基础值,危险色不跟着变。
  3. 命名没语义、没分类green1var2spacing4。名字没说清用途,团队看不懂、用错。
  4. Token 只给开发、设计师不管:设计稿里照样手填 #07C160。设计与代码不同步,又一个"双份真相"。

反模式共同点:让决策失去了"唯一源头"。谁破坏源头,谁就回到"改几十处"。

边界:Token 不是万能的

  • Token 管"值/语义",不管"布局结构"spacing-card 管距离,管不了这个卡片放哪、多大——那是 Auto-Layout 和组件的事。
  • Token 需要治理:Token 会越建越多,要约定命名规范、定期合并重复,否则"Token 之乱"不输"硬编码之乱"。
  • Token 是终点,也是起点:它是流程⑦设计系统的收官,但真正让设计系统"活"在团队里,靠的是组件库 + 规范 + 工具链持续维护。

CSS 映射:Token 是怎么落到代码的

设计里的 color-brand-primaryspacing-card,在 Web 端就是一段 CSS 变量,靠 var() 引用成网。上面 --space-unit → --spacing-card 那段就是真实映射的缩影。交付时,Style Dictionary 这类工具能把 Token 一键导出成 iOS、安卓、Web 各端代码,这就是"Token 工程化"的经典实践。

误区

误解正解
"Token = 给变量改个漂亮名字"变量只存值,Token 是设计决策的源头、语义、出处
"Token 只给开发用"设计师在设计工具里同样用 Token,开发与设计两端喊同一个名字
"Token 是一次性值,建完就得了"Token 要有引用关系(如 spacing-card = spacing-md × 2),互相引用才成体系
"有样式就够了,不用 Token"样式是工具层复用,管不到跨端;Token 是决策源头、跨端统一,样式引用 Token
"Token 是给大厂用的,我做小项目用不上"小项目也受益:哪怕只有 10 个 Token,改一处全变,也比硬编码强

练习

即时题 Q1:为什么样式解决了设计文件内复用,却解决不了跨端统一?

答案样式只在当前设计工具/文件里生效;真产品有 iOS/安卓/Web 多端,各自的代码和文件各自一套,样式管不到。Token 是跨工具的共享"数据源",才能统一。

即时题 Q2:基础 Token 和语义 Token 各存什么?各举一个微信例子。

答案基础 Token 存最原始的原子值,如 `#07C160`(`color-brand-primary`)、`8px`(`spacing-base`);语义 Token 存"用途",如 `color-bg`(背景)、`spacing-card`(卡片间距)。原料 vs 菜谱。

即时题 Q3(反模式):spacing-card 直接写死 16px,而不是 spacing-base × 2,错在哪?

答案它复制了数值、断了引用关系。改 `spacing-base` 时 `spacing-card` 不跟着变,间距体系分裂,又回到"改一处追 N 处"。

模块题 微信要换品牌绿,从 #07C160 换成 #07D160。请用"硬编码值"和"Token 体系"两种做法,分别说出改动波及的范围,并说明 Token 为什么省力。

参考思路硬编码:去 iOS/安卓/Web/小程序/设计稿里逐个找 `#07C160`,几十处、跨端、跨语言、易漏,还可能各端改得不一样。Token 体系:只改 `color-brand-primary` 这一个 Token,所有引用它的组件、样式、端一次变。关键点:数值一旦有了唯一源头,改动成本就从"追几十处"变成"改一处"。

迷你案例 把微信的核心设计值整理成一份"Token 表":

  1. 打开微信设计文件,把出现的颜色值整理出来,每个起一个名字,标清是"基础"还是"语义":微信绿 #07C160、微信红 #FA5151、正文字 #1F1F1F、辅助灰字 #999999
  2. 找最小的间距单位(通常是 8px),作为 spacing-base
  3. 把卡片内边距写成引用关系:spacing-card = spacing-base × 2
  4. 把"红色"拆成语义 color-danger(用在未读角标、删除、报错),验证它是否引用了基础红。
  5. 最后在心里回答:哪天换品牌绿,你要改几个 Token?——答案应该是一个。

做完你就懂了:界面不是"一堆数值",而是一张互相引用的 Token 网。设计系统到这一步,就从"画得好看"升级成了"管得住、改得动、跨端统一"的工程。

素材

  • 👉 打开交互演示:Design Tokens — 改一个基础 Token,按钮/图标/强调全链联动变色,看 Token 互相引用成网
  • Style Dictionary:把 Token 一键导出成 iOS/安卓/Web 代码的工具,是"Token 工程化"的经典实践。
  • Design Tokens W3C 规范:设计 Token 的通用格式标准,看它如何跨工具、跨端共享。
  • Penpot 样式(12)衔接:Penpot 样式是 Token 的落地雏形,本节把它升级成"命名 + 引用"的 Token 体系。
  • 后续衔接:23 Design Tokens(决策源头,流程⑦终点)→ 组件化(把图形 + Token 包成可复用组件)→ 设计系统整体治理。