从 Token 到 Page:设计语言七层协议完整拆解
2026/9/15 4:42:14 网站建设 项目流程

在工程世界里,协议是无处不在的隐形秩序。CAN 总线、SPI、IIC、Modbus、RTSP、PCIE、USB,每一种协议都是收发双方事先约定好的沟通规则:数据从哪一位开始读、校验码怎么算、重试机制怎么走。只要有一方不遵守约定,整个系统就会立刻变成一地鸡毛。这个道理放到设计领域也一样成立。你做一个页面、维护一套组件库、治理跨业务线的视觉一致性,本质上绕不开同一件事:设计语言需要一份属于自己的“协议”。

把设计语言拆成从 Token 到 Page 的一条完整的结构化路径,这个想法听起来有点理想化,真做起来却一点也不玄。七层协议不等于七个新文件,也不代表你要把现有组件库推翻重来。它是一套调用约定,用来回答几个每天都会碰到的问题:这个页面的主色到底应该从哪一层取?这个按钮为什么能用那个颜色?主题切换时,哪些页面一定会受影响?新同事写几周代码,会不会又把设计系统变成一场混乱?

这篇文章里,我会把这套七层协议完整拆开:每一层是干什么的、层与层之间如何衔接、落地时从哪里入手,以及我实际项目中踩过的坑。适合正在做或者准备做设计系统的人看,无论你是负责 token 管理的设计师、前端组件库维护者,还是多业务线里的体验一致性负责人,这套思路都可以直接拿去参考。我不保证看完你就能一步到位,但至少,你能知道下一次改颜色时,该从哪一层动手。

1. 为什么设计语言需要七层协议,而不是一套组件库

1.1 组件库只能回答“有什么”,协议回答“怎么用”

很多团队对设计系统的理解,停留在“有一堆精心设计的组件”这个层面。按钮、输入框、下拉菜单、弹窗,样式齐全,文档也有,看起来万事大吉。真到落地的时候,问题就冒出来了:同样一个按钮,在营销页里用了紫色的 hover 色,在后台里又换成了深蓝色;同一个间距,有的页面用 8px,有的页面用 10px,设计师看着都不太对,但谁也说不清到底哪里越界了。

这不是组件库的问题,而是缺少“协议”的问题。组件库相当于一间装修材料齐全的仓库,里面什么瓷砖、油漆、木板都有,但没有人告诉工人哪面墙能用哪种漆、多大幅度允许改、改了之后要承担什么后果。协议要做的,就是把这些规则显式化:定义哪些值可以出现在哪个层级、每一层之间如何引用、什么情况下可以覆写、什么情况下不允许碰。

我在刚接触 token 体系的时候,也犯过同样的错误。当时团队把几百个颜色变量全部铺在 Figma 和 SCSS 文件里,命名也算规范,但业务一多,页面还是脏得很快。后来才意识到,光有变量和组件远远不够,缺少的是让变量、组件、页面各归其位的调用边界。七层协议的核心,就是在“值”和“页面”之间,建立一条谁都不能跳过中间层的单向链路。

1.2 结构化路径:让每个像素都能查户口

“结构化路径”这个词听起来学术,实际含义很朴素:页面上的任何一个视觉属性,都能沿着一条可追踪的链路,一级一级回溯到最底层的全局 Token;反过来,任何一个最底层的 Token 发生变化,你也可以沿同一条链路预估出哪些组件、哪些页面会被影响。这就是把设计数据从“一团状态”变成“一条河流”。

打个比方,如果把页面比作一桌菜,那设计 Token 是菜市场买回来的原材料,语义 Token 是菜谱上写的“半勺盐”“两勺生抽”,组件 Token 是后厨对每一道菜的具体操作标准,组件是已经出锅的菜,模式是几道菜的固定搭配,模板是宴会桌的摆盘规则,Page 才是最终端到客人面前的那一桌饭。每一层都有存在的理由,每一层都只与相邻层对话,这样就再也不会出现“后厨直接去菜市场买了一把香菜”这种混乱。

这一节想强调的结论是:分层不是目的,可预测才是目的。七层设计语言协议追求的,不是结构漂亮,而是“任何人拿到一个页面,都能在五分钟内说清楚它为什么长这样”。一旦这个能力建立起来,主题切换、品牌升级、跨端适配、新人上手,都会从碰运气变成按流程走。

2. 七层协议逐层拆解:从 Token 到 Page

2.1 第1层:设计 Token(原始值)

最底层的设计 Token,是所有视觉变量的原始值。它只回答“可以是什么”,不回答“为什么用它”。比如色值#2B6CD4、字号14px、间距8px、圆角4px、阴影0 2px 8px rgba(0,0,0,0.12),这些都是最原始的设计原子。这一层最常见的形式是少量核心文件:tokens.json、tokens.css,或者设计工具里的基础样式库。

在这一层,我最推荐的做法是中性的命名,比如颜色用blue-500neutral-100,间隔用space-2space-4,圆角用radius-smradius-md。千万不要在这里写业务含义,比如color-dangercolor-brand,因为业务含义是第2层该干的事。如果你把业务含义写进原始值层,将来换主题或换品牌色的时候,底层文件会跟着业务一起被污染,整个设计系统就失去了稳定锚点。

原始值的数量需要严格控制。颜色几十个、间距十几个、字号十几个、圆角四五个、阴影七八个,已经算比较健康的规模。每增加一个原始值,都应该像在代码库中新增全局变量一样慎重。如果发现两个色值肉眼几乎分不出来,先不要急着合并,把它们放在一起观察三个月再做决定,因为有很多近似色是专门用于 hover、disabled 等特殊状态的。

2.2 第2层:语义 Token(业务翻译层)

语义 Token 是第1层到第3层之间的翻译器。它把原始值翻译成具有业务含义的名字,比如color/bg/primarycolor/text/errorspacing/scale-4radius/control。这一层最重要的规则是:只能引用第1层,不能自己发明新值;同时,这一层的命名一旦确立,就要在同一套设计语言的内部保持长期稳定。

语义 Token 解决的最典型问题是“换肤”。同一套组件,在品牌 A 下 primary 色是蓝色,在品牌 B 下可能变成橙色。如果组件写的是color/bg/primary,那换肤时只需要修改第2层的映射关系,让它指向不同的第1层原始值。组件层完全不用动。但如果组件里写死了blue-500,换肤就成了一个噩梦。这个层级的价值,做过一次白标项目或者多品牌项目的人会体会得很深。

很多团队会问:语义 Token 是不是越多越好?反正多加几个映射又没成本。答案是恰恰相反。语义 Token 是设计系统的公共 API,每增加一个,维护成本都会上升。我见过一张设计稿里出现十几个语义颜色,什么color/text/linkcolor/text/link-hovercolor/text/link-active,其实后两个完全可以合并到一个枚举状态里。语义 Token 应该按角色收敛,而不是按 UI 状态穷举。

2.3 第3层:组件 Token(组件内部契约)

组件 Token 是很多人会忽略的一层,也是七层协议里承上启下的关键层。每一个组件都维护一张自己的 Token 清单,比如按钮组件有button/bg/defaultbutton/bg/hoverbutton/text/defaultbutton/border/defaultbutton/radius。这些组件 Token 只允许引用第2层的语义 Token,不允许直接引用第1层原始值。

组件 Token 解决的是“组件属于自己的接口问题”。当业务方问“这个按钮颜色可以改吗”的时候,你不需要翻组件源码,只需要打开按钮组件的 Token 清单,看看哪些属性允许覆写、取值范围是什么。它相当于把组件内部实现和外部配置解耦。没有这一层,组件库很容易变成一个个黑盒,改样式只能靠人或“设计稿微调”。

在实际操作中,组件 Token 的命名最好体现出“组件-属性-状态”三段结构。例如button/bg/hover,就有明确的层级感。这么做还有一个额外的好处:在工具链中你可以很方便地扫描出某个组件支持哪些配置项,甚至可以自动生成组件的“可配置化文档”。我强烈建议在创建新组件时,先把组件 Token 清单写出来,再写组件代码或设计稿,顺序反了就会很被动。

2.4 第4层:组件(标准原子单元)

组件是用户真正能感知到的基础单元。输入框、按钮、标签、弹窗、下拉框,都属于这一层。组件内部只消费第3层的组件 Token,不允许出现业务数据、页面布局逻辑或特殊状态逻辑。到这里,组件已经可以独立使用,也具备了跨页面复用的条件。

组件层的核心要求是“接口稳定,实现自由”。对外暴露的 props 和 Token 配置项一旦确定,就不要轻易变更;内部的 DOM 结构、样式实现方式则可以根据技术方案随时优化。这个思想跟后端服务对外提供 API 很像:只要接口契约不变,底层怎么重构用户无感知。设计系统最害怕的就是“为了改个圆角,改了组件,结果影响了好几个页面”这类连锁事故,组件 Token 层就是为了挡住这种事故。

组件层的另一个职责是状态完整性。每个组件必须明确列出 default、hover、active、disabled、focus 等状态,以及对应的组件 Token。如果某个状态没有定义值,系统应该主动报错而不是静默跳过一次样式。很多可访问性问题就出在这里:hover 有反馈、focus 却没有,键盘用户完全不知道焦点在哪。组件协议上把这些状态列入强制检查项,是提升无障碍体验最省力的一步。

2.5 第5层:内容模式(组件协作规则)

单个组件解决不了所有问题,当多个组件组合在一起形成固定协作方式时,就出现了内容模式。比如筛选区域、列表头、空状态、表单页头、搜索结果页、分页工具栏,这些都属于模式而非组件。模式层不生产新组件,它定义的是“多个组件如何配合”:栅格占几列、间距用什么刻度、组件之间的对齐关系、键盘 Tab 的移动顺序。

内容模式是设计系统中“看不见但总在重复”的部分。很多团队觉得页面看起来不整齐,不是因为组件不好看,而是模式没有沉淀下来。同一个表格,A 页面筛选器在左边,B 页面筛选器在上方,C 页面干脆把筛选和搜索混在一起。当模式建立起来之后,新页面只需要选择“用哪个模式”,而不是重新发明一次布局。

模式层的产出物是一套规则文档,通常配合 Figma 的 Auto Layout 组件和前端代码片段一起维护。我建议模式层的生命周期比组件层更稳定,不要频繁新增。一个设计系统有二十个左右的常用模式,已经能覆盖大多数后台和营销场景。评估一个新模式是否值得加入,标准很简单:这个组合方式是否已经在至少三个页面中出现,并且有统一的交互语义。没达到这个标准,先不要沉淀。

2.6 第6层:页面模板(结构骨架)

页面模板是在具体内容填充之前的“半成品页面”。它确定页面的整体骨架:头部区域放什么、侧边栏多宽、导航在哪、内容区如何分区、空白状态怎么处理。模板不绑定真实业务数据,只是把第5层的模式按一定结构组织起来。常见的模板有列表页模板、详情页模板、Dashboard 模板、表单页模板、文章阅读页模板。

模板存在的意义,是让“页面结构”本身也可以复用。我见过不少团队,组件做得很规范,但每个页面还是长得不一样,因为没有人把页面骨架也标准化。有了模板之后,产品和设计在规划新页面时,第一件事不是画线框图,而是选一个结构合适的模板,在线框图上做微调。这能大幅减少跨页面的结构漂移。

模板层的重点在于“允许什么层级做调整,不允许什么层级做调整”。我会推荐模板中可以调整模式的顺序、间距比例、卡片密度,但禁止调整基础组件的大小和字体层级。否则,模板就不起约束作用了。模板层的变更需要经过设计系统负责人评审,因为它会直接影响所有基于该模板的页面,影响面通常比组件层更大。

2.7 第7层:Page(最终实例)

Page 是整个结构化路径的终点,也是用户真正访问的页面。它由模板(第6层)提供结构,由内容模式(第5层)提供协作规则,由组件(第4层)提供基础单元,填充真实的业务内容与图片文案,最终形成一个页面实例。到这里,一条从 Token 到 Page 的完整链路终于闭合。

Page 层最严格的约束是:页面代码或设计稿中,不允许出现任何直接引用的第1层原始值,也不允许直接修改第2层语义 Token 的映射。页面只能通过模板和组件消费系统中的既有配置。如果页面确实需要差异,必须走“页面级组件 Token 覆写”机制,并且显式声明覆写原因。这一条规则看着严苛,但实际上保护了后续所有维护工作。

为什么要这么严格?因为一旦允许页面直接调用底层值,token 变更的影响分析就失效了。你今天在第1层把blue-500的色值调深了一点,结果发现某几个页面颜色变了,但你无法从链路中找到它们为什么会变,因为它们在页面层直接引用了底层值。一个页面这样没关系,一百个页面这样,系统就回到了“谁也不敢改样式”的僵局。Page 层的干净,是整个系统可维护性的血压计。

3. 协议的关键动作:Token 生命周期、命名与引用边界

3.1 Token 生命周期:签发、消费、废弃,别直接删

做过接口鉴权的人都知道,Token 不是永生不死的。JWT 有有效期,过期之后要续签,续签失败要重新登录,注销之后还要加黑名单。设计 Token 也是同样的道理。一个 Token 从诞生到被抛弃,也要经历明确的周期:提案、评审、发布、消费、弃用、下线。很多设计系统最后会腐烂,不是因为没有 Token,而是因为没有人管理 Token 的生命周期。

尤其重要的一点是:不要直接删除 Token,而是要“先废弃、再移除”。代码里最常见的场景是,设计师觉得某个颜色不好看,直接在 token 文件里把值改掉,然后全局搜索一看,颜色变了,感觉万事大吉。结果三个月后又有业务跳出来说,当年那个颜色是用来表示某种特殊状态的,现在状态没了色值改了,用户完全分不清楚。正确的做法是给已废弃 Token 一个 deprecated 标记,并设置至少一个发布周期的迁移窗口,让大家有时间改引用关系。

我在项目里会给 Token 加四个状态:active、deprecated、sunset、removed。active 表示正常可用;deprecated 表示还能用但不推荐新项目引用;sunset 表示进入倒计时,之后会移除;removed 表示已经不存在。任何状态变更都记录在变更日志里。这种方式很像接口版本管理,开始会觉得流程繁琐,坚持几个版本后,你就能准确回答“这个颜色还能不能用、什么时候下线、现在还有多少页面在引用”。

3.2 命名协议:一个名字该携带多少信息

命名是协议最容易上手、也最容易出效果的部分。好的 Token 命名应该做到:看到名字,你就知道它属于哪一层、服务于哪个组件、对应什么状态、值是什么类型。比如button/bg/hover,一眼就知道这是按钮的背景 hover 状态;spacing/scale-4,一眼就知道是间距体系里的第四档刻度;color/text/error,一眼就知道是用于文本的错误色。

命名协议通常会包含几个强制约定:第一,层级前缀要统一,组件 Token 必须带组件名,语义 Token 必须带语义域,原始值 Token 必须带类型。第二,状态字段要按固定顺序排列,比如“组件-属性-状态”,不能有的写hover/button/bg,有的写button/bg/hover。第三,禁止在命名里使用“页面名+随机意向词”,比如homepage-bluecampaign-purple,这种名字等于把页面业务语义固化到系统里,换页面就作废。

有些读者可能会问,命名真有那么重要吗?我的体验是,命名是协议在代码审查里最容易被自动化的部分。你可以用正则和 lint 工具检查 token 命名是否符合规范,而不需要人工评审。这等于把设计系统的“卫生标准”塞进了开发流程,每一个不符合规范的命名都会在提交代码时被拦截。就这一条,足以让设计系统在一段时间后依然保持干净。命名不是一个审美问题,它是一个天然的强制性接口。

3.3 引用边界:每一层只与相邻层通话

七层协议的本质是单向依赖。第1层只被第2层引用,第2层只被第3层引用,以此类推;跨层引用是系统腐败的头号原因。我把这项规则叫“相邻层通话协议”,它对应到工程世界里,就像网络分层模型一样,每一层只需要关心它与上下邻居的接口,不用关心更远处的实现。

具体到实际操作中,会出现几种常见的跨层行为,需要重点拦截。第一种:组件内部直接写死了十六进制色值,这个最明显,也最好查。第二种:页面样式文件里直接用 CSS 变量引用了第1层原始值,绕过了组件 Token,这种在后台系统非常常见,因为页面开发者觉得“我直接用个颜色变量多省事”。第三种:语义 Token 在设计稿里被直接赋给了某个页面元素,没有经过组件层。这三种行为如果不加约束,都会逐渐瓦解整个链路的可追踪性。

拦截跨层引用的手段,不能只靠人的自觉。推荐的做法是在 CI 或者代码审查阶段加入静态扫描,比如用脚本扫描组件目录中是否出现色值、是否引用了未授权的 token 层级。设计侧也是一样,Figma 插件可以检查某个选中的元素是用变量还是硬编码颜色。拦截不是目的,目的是让“没有协议的改动”在进入系统之前就被发现,而不是等它变成用户看见的 bug 再去返工。

4. 落地实操:从现有组件库走向七层协议

4.1 盘点:把设计稿拆成 Token

如果你现在有一套成熟的组件库,但还没有分层协议,我建议不要推倒重来,而是先做一次完整的“设计资产盘点”。把设计稿和前端样式文件里的颜色、字号、间距、圆角、阴影、动效全部提取出来,去重并归类。这一阶段不急着映射语义,先把“有什么”搞清楚。常见情况是,盘点完你会发现一百多个色值,其中真正独立的不超过四十个。

提取工作量不小,但有一些高效路径。前端可以从 SCSS/LESS/CSS 文件里搜索所有十六进制色值和 CSS 变量;设计侧可以在 Figma 里查看所有样式库的值;两者交叉对比,可以快速找出“设计用了但代码没有”“代码有但设计没有”的差集。这个阶段产出物是一张原始值清单,建议以 JSON 或 CSV 的格式管理,方便后续导入 token 工具链。

盘点时最容易踩的坑是“肉眼觉得一样就合并”。#2B6CD4#2C6CD4差 1 个色阶,肉眼很难分辨,但可能有特殊用途。我的建议是:完全相同的值合并;肉眼接近但不完全相同的值先保留,标注“疑似重复”,等对应组件确认后再决定。合并过快会导致组件出现不可预期的颜色变化,这一步宁慢勿快。

4.2 映射:建立三层 Token 对照表

盘点完成之后,下一步是建立映射表。拿颜色举例,原始值层是blue-500: #2B6CD4,语义层是color/bg/primary: blue-500,组件层是button/bg/default: color/bg/primary。三层对照表需要同时包含“从值到语义”“从语义到组件”两个方向,这样任何一层的变更,都能迅速评估影响范围。

映射表可以用电子表格,也可以用样式字典(Style Dictionary)这样的工具产出。我更推荐用代码形式维护,因为可以配合版本管理和自动化生成。比如用 JSON 定义第1层原始值,用另一个 JSON 维护第2层和第3层的映射关系。这样一来,发布新主题时,你只需要换一套第1层 JSON 文件,其他层完全不用动。这在多品牌、多主题项目里是杀手级能力。

在映射过程中,会有很多让人纠结的细节。比如某个组件的背景色,到底应该映射到color/bg/primary,还是单独建一个button/bg/primary?我的经验是:如果这个语义色在多个组件中通用,就放在语义层;如果它只服务于这个组件的某个特定状态,就放在组件 Token 层。判断标准是“复用频率”。复用频率高就向上沉淀,复用频率低就向下收敛,不要为了追求层次丰富而人为制造冗余。

4.3 约束:在代码仓库里拦住越界值

协议写得再漂亮,不落地执行就是废纸。代码侧最有效的落地手段是自动化检查。我习惯用一条规则清单来做代码仓库的“卫兵”:第一,组件目录下不允许出现十六进制色值、具体字号值、具体间距值;第二,组件样式文件只能引用组件 Token;第三,页面文件不允许直接引用第1层原始值;第四,所有 Token 命名必须符合正则规范。

实际操作中,可以用一条简单的 grep 命令先做一轮扫描,比如在 CI 脚本里加入:

grep -rnE "#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})" src/components --include="*.tsx" --include="*.css" --include="*.scss" | head -50

如果输出的数量不为零,那就说明组件目录里出现了直接写死的颜色值,构建应该失败并提示开发者改用组件 Token。等扫描规则跑顺之后,再逐步加入更细的规则:禁止页面引用底层 token、禁止 CSS 变量跨层级引用、token 命名必须通过正则校验。这些规则每多一条,设计系统未来的维护成本就低一分。

当然,自动化检查也存在误报风险。比如组件里如果包含了一段示例图片的数据,图片地址里可能带#,或者某些 SVG 图标里有颜色值。所以规则上线初期建议先跑“警告”模式,只提醒不拦截,等规则名单稳定之后再加入阻塞模式。这套流程本质上是把设计系统的可维护性,从“靠人提醒”升级为“靠流程保证”。

4.4 验证:从 Page 反查整条链路

当协议和约束都建好之后,需要一套验证方法。最直接的方式是挑一个典型页面,从页面元素反向追溯,一直查到第1层原始值。比如“商品列表页的筛选按钮”,它的背景色链路应该是:button/bg/default(第3层)→color/bg/primary(第2层)→blue-500(第1层)。只要每个页面都能完成这个反查,链路就一定是通的。

反向验证还有另一个角度:改动第1层某个值,看影响范围是否与预期一致。比如把blue-500#2B6CD4改成#1A5DB4,你的影响清单里应该出现所有映射了该语义 Token 的组件,并且不会出现任何与蓝色无关的组件。如果影响列表里混进了奇怪的东西,大概率是出现了跨层引用,需要回头排查。

建议把“链路验证”变成每个迭代的例行工作。哪怕只是随机选一个页面做反查,也能持续发现协议被绕过的地方。我在项目里每隔两周会做一次这样的抽样,并把结果贴在团队 wiki 上。这个方法的好处是,不需要等系统彻底腐烂再重启,它时刻都在提醒所有人,设计系统是有约束的,同时也是可维护的。

5. 实战踩坑记录与排查速查表

5.1 红色到底表示危险还是促销?

我遇到过最典型的语义冲突:同样的红色色值,在一个业务线里表示“错误和危险”,在另一个业务线里表示“促销和折扣”。如果团队在建语义 Token 时直接用了color/red这样的色相名,那么业务 A 和业务 B 都要改这个 token,结果就是谁都不敢改,因为一改就影响另一个业务的语义。

这个问题的解法,是把“色相”从语义 Token 命名中剥离。语义 Token 应该按“角色”命名,比如color/text/dangercolor/bg/marketingcolor/text/error,让它们各自映射到同一个原始值或者不同原始值都可以。红色在危险场景叫danger,在促销场景叫discount,两者互不干扰,底层指向同一个色值时还能共享同一个原始色板。色相词只出现在第1层,不应该出现在第2层以后的任何层级。

这个坑给我的教训是:语义 Token 的命名,尊重业务语言比尊重设计语言更重要。你可以在团队内部把第1层叫做red-500,但第2层必须让业务方一看就明白“这是用于错误提示的文本颜色,还是用于促销标签的背景色”。只要语义命名够清晰,多业务线共存就不容易互相踩脚。

5.2 为什么组件改完样式,页面还是旧值

组件 Token 落地过程中,另一个高频问题是“组件改了 token,但页面显示还是旧值”。排查之后发现,原因是页面样式文件里还有一份“局部覆写”,它比组件 Token 的优先级更高,直接把组件层的样式盖掉了。这类局部覆写通常来自早期业务开发时的“应急方案”,长期沉积下来就成了样式债。

处理办法分两步。第一步,先扫描出所有页面级样式文件里存在的硬编码样式值,把它们分类:能删除的直接删除、需要保留的转化为页面级组件 Token 覆写。第二步,在代码规范里禁止组件样式文件之外的硬编码覆盖,也就是说页面确实需要调整某个组件样式时,必须修改该组件对外暴露的 Token 配置项,而不是直接写一份更高优先级的 CSS。

这种问题在排查时最耗时的其实是找覆盖关系。如果不提前建立协议,你往往要全局搜索某个类名,然后一层层看样式优先级,才能定位到“罪魁祸首”。有了七层协议之后,链路的每一环都是可预期的,你只需要从 Page 往下一层一层检查,在哪一层发现了非协议引用,问题就在哪里。排查时间能从几个小时缩短到十几分钟,这个效率收益很快就能体现出来。

5.3 页面级别的“例外”如何管理

很多团队听到“页面不允许直接引用底层值”这条规则时的第一反应是:太死板了。事实上,完全禁止页面例外并不现实,营销页、活动页、品牌页总有各种个性化需求。关键不是禁止例外,而是让例外走协议。

我的做法是,允许页面层做“页面级组件 Token 覆写”。比如某个活动页需要按钮 hover 变成金色,它可以在页面级配置里声明一个映射:button/bg/hover: custom/golden-hover,并且附带覆写原因。这条配置会被记录到变更日志,后续任何 Token 变更时都能看到“这个页面有一次特殊覆写,它的调用链在 Page 层,而不是组件层”。这样就既保留了灵活性,又不破坏整体链路的可追溯性。

不过,页面级覆写也要有阈值,不能让例外变成常态。我见过一个项目,三个月后页面级覆写积累了上百条,比组件 Token 还多,最后大家又开始疲于应付各种“特别颜色”。所以需要定期清理:每次大版本迭代时,检查所有页面级覆写,看它对应的业务需求是否仍然成立。不成立的覆写直接删除,成立的继续保留。这个机制能保证系统在“通用”和“灵活”之间找到一个相对健康的平衡点。

5.4 常见问题速查表

最后把我在实操中经常被问到的问题整理成一张速查表,按“现象 - 可能原因 - 解决动作”的格式,方便大家对照排查。

现象可能原因解决动作
页面出现组件库中不存在的颜色Page 层直接引用了第1层原始值或硬编码色值搜索页面样式中的十六进制色值,替换为第2层/第3层 Token
修改组件 Token 后,页面样式无变化页面级存在更高优先级的局部覆写扫描页面样式,清除硬编码覆盖,改为组件 Token 配置项
同一语义色在不同端显示不一致第2层语义 Token 在不同端映射到了不同原始值检查各端第2层映射文件,统一映射关系
切换主题后部分组件未更新组件内部存在跨层引用或硬编码值清理组件内部的非 Token 引用,改用组件 Token
新组件上线后风格与设计系统不一致新组件没有定义组件 Token,直接抄了旧组件样式先写组件 Token 清单,再写组件实现
想删除某个 Token,但不知道哪些页面在用缺少 Token 引用统计与状态管理引入 Token 生命周期状态,加入 CI 引用扫描

这套速查表不是全部场景,但覆盖了我经历过的 80% 问题。核心逻辑其实只有一句话:任何不符合分层协议的引用,终将以维护成本的方式付出代价。你可以选择现在支付那一点点结构成本,也可以选择在未来的某一次紧急改版里,带着团队在全局搜索里焦头烂额。

我在把七层协议真正推行到项目里之后,最大的感受是:设计系统本质上是“让别人始终有依据地做选择”。它不限制创造力,而是把创造力放到对的位置。分层不是给设计师和工程师戴枷锁,而是让所有人不用每天纠结“这个变量到底该不该用”。Token 从哪一层来、到哪一层去,路径清晰了,改版的恐惧感自然就低了。

如果你想上手试,我建议先不要做全套七层。挑一个最痛的点,比如先建好第1层、第2层和第3层的颜色链路,并把组件里的硬编码色值清干净。等这一条链路跑顺,再逐步扩展到间距、字体、圆角、阴影,以及模板层和页面层。协议是长出来的,不是一口气设计出来的。哪怕一开始只有三层,也比没有协议强一百倍。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询