设计系统

蓝色设计 Token:Tailwind、Material 与 Ant Design 的区别

比较常见蓝色 Token 的准确色值与色板版本,通过组件实例建立语义映射,避免把相似名称当成相同颜色。

颜色名称需要与色板版本一起记录

blue-500 表示某个色板中的一个位置,并不代表通用的蓝色。Tailwind CSS、Material Design 和 Ant Design 的命名规则与色值各不相同,即使这些颜色在产品中承担相似角色,也不能直接互换。

记录颜色时,应同时保存组件库、色板版本、Token 名称和准确色值。Tailwind v3 使用 HEX 色板值,Tailwind v4 的默认颜色使用 OKLCH 定义。本文的 #3B82F6 对应 Tailwind v3 的 blue-500,迁移前应检查项目实际版本和 CSS 变量的最终值。

区分基础色板、语义与组件三个层级

实际项目可以使用三个层级组织颜色:基础色板 Token 保存可复用色值,例如 palette-blue-600;语义 Token 表达用途,例如 action-background;组件 Token 对应具体位置,例如 button-primary-background。三个层级通过引用连接,既允许品牌调整向下传递,也能为某些组件保留有明确原因的例外。

主按钮和正文链接可能最初使用同一个蓝色,但它们的约束不同。按钮要保证标签与填充背景之间的可读性,链接要在页面底色上清晰,还要让读者能够从相邻正文中辨认出来。如果全部绑定到一个 brand-blue,后续修改某一种场景时,就容易无意中影响另一种场景。

Ant Design 文档将自身的主题处理分为 Seed、Map 和 Alias Token。colorPrimary 这样的种子会参与生成后续主题值,不意味着每一种主色状态都原样使用种子值。接入组件库时,应检查最终主题值和组件覆盖配置,再建立应用自己的语义映射。

先比较色值,再分配界面角色

下表列出有明确版本背景的颜色参考。Material Design 2014 的 Indigo 500 与 Material 3 生成的色调色板不是同一套系统。Ant Design 的主色种子也可以被主题覆盖,因此实际产品中的颜色可能与默认值不同。

替换这些看起来相近的蓝色之前,需要检查文字对比度、悬停状态与周围背景。先将它们转换成项目使用的颜色格式,再放进真实组件比较。

不同设计系统中的颜色参考
色板参考TokenHEXRGB
Tailwind CSS v3blue-500#3B82F659, 130, 246
Material Design 2014Indigo 500#3F51B563, 81, 181
Material Design 2014Light Blue 500#03A9F43, 169, 244
Ant Design v5 默认值colorPrimary / blue-6#1677FF22, 119, 255

比较颜色时同时保留颜色空间信息

对于不透明颜色,HEX 与整数 RGB 表达同一组 sRGB 通道。因此,把 #3B82F6 写成 rgb(59, 130, 246) 只改变格式,不会生成新的色板。OKLCH 则使用明度、彩度与色相描述颜色,其坐标不能直接填入 RGB 通道,也不能通过与 HEX 字符串比较数字来判断颜色是否相同。

Tailwind v4 文档中的默认色板使用 OKLCH。如果构建链支持,应保留原始定义;如果某个导出环节必须使用 HEX,则需要记录转换方式,以及超出目标色域的颜色如何处理。转换为 sRGB 时可能损失彩度,导出的近似值不应在没有说明的情况下覆盖设计系统中的原始定义。

评审时应统一背景、颜色空间与组件尺寸。不同组件库中的 500 档位不表示共同的明度。可以通过视觉检查确认品牌表达,再用准确对比度确认文字可读性;这两项判断各自解决不同问题,都需要保留。

把色板值映射到语义 Token

将基础色板与组件用途分开维护。action-background 这样的语义名称能说明颜色承担的职责,也方便以后替换组件库色板,而不必重命名所有按钮和链接。

下面的 Tailwind v3 示例使用 blue-600 作为普通按钮背景。白字在 #3B82F6 上的对比度约为 3.68:1,低于 WCAG AA 对普通文字要求的 4.5:1;白字在 #2563EB 上则约为 5.17:1。选择更深的背景是具体组件的判断,不能据此断言某套色板始终更好。

CSS
:root {
  /* Tailwind CSS v3 色板参考 */
  --palette-blue-500: #3b82f6;
  --palette-blue-600: #2563eb;
  --palette-blue-700: #1d4ed8;

  --action-background: var(--palette-blue-600);
  --action-background-hover: var(--palette-blue-700);
  --action-text: #ffffff;
}

.button {
  background: var(--action-background);
  color: var(--action-text);
}

.button:hover {
  background: var(--action-background-hover);
}

为明暗主题建立组件状态矩阵

逐一列出普通、悬停、按下、选中和键盘聚焦状态的前景与背景。透明按钮、描边按钮还需要记录所在页面的实际底色。加深悬停背景可能提高白字对比度,但浅色选中背景通常需要单独配置深色文字。应检查最终组合,不能默认沿色板移动一个档位就会改善可读性。

深色主题需要重新映射语义角色。直接反转色板,或照搬浅色主题的操作色,可能让链接融入深色背景,也可能让焦点环与按钮边缘难以区分。应先通过组件库支持的主题机制生成结果,再检查标签、边框与状态指示在实际表面上的表现。

将状态例外与原因一起记录。例如,品牌蓝继续用于插画,而带小号白字的按钮使用更深的操作色。这样既保留品牌参考,也能让无障碍决策得到复核。上面的 CSS 只展示 Token 引用关系,完整按钮仍需另外实现键盘焦点样式与交互行为。

在真实组件里验证迁移结果

先整理当前主题实际输出的颜色,包括项目自定义覆盖。再映射操作按钮、链接、焦点指示、选中背景和文字等语义角色。不要因为数字档位相同,就替换项目里所有对应的蓝色。

分别检查普通、悬停、按下和聚焦状态与相邻颜色的关系。文字对比度应基于最终合成的背景计算,包括透明层和叠加效果。为焦点保留可见提示,为链接与状态提供颜色之外的识别线索。

最后将新色板版本与对比度检查结果一起记录在设计 Token 文档中。可以使用下方颜色详情核对数值,再用分析器确认前景色与背景色的可读性。

一份可复核的迁移记录应包含旧值、新语义 Token、各主题下的最终值、受影响组件和对比度组合。先验证一个代表性组件,再批量替换。截图有助于发现视觉回归,保存的测量值则说明为什么可以接受这次调整,也方便下一次升级沿用相同检查流程。

来源与延伸阅读

← 返回全部文章