Design Tokens 标准
Design Tokens 是主题和业务页面之间的共享语言。业务页面不应把颜色、字号、间距、圆角、边框、焦点和状态色散落在局部配置中;应优先使用 ThemeData 和组件公开的 token。
Token 分层
| 层级 | 来源 | 用途 |
|---|---|---|
| Global token | ThemeData |
框架基础颜色、字体、尺寸、圆角、边框、焦点和滚动条。 |
| Component token | 组件级样式 token | 某一类组件的状态色、padding、border、font、radius。 |
| Component state | 组件当前状态 | hovered、pressed、focused、selected、disabled、loading 等交互状态。 |
| Resolved value | 最终显示值 | 根据 token 和 state 得到的颜色、位置和尺寸。 |
业务页面应优先复用已有语义 token,而不是直接写固定色值。确实需要品牌化或业务专属视觉时,应把自定义值收敛在应用主题或统一样式适配层中。
颜色 Token
颜色必须表达语义,不以具体色名作为业务含义。
| 语义 | 推荐来源 | 用途 |
|---|---|---|
surfaceWindow |
ThemeData |
应用主背景。 |
surfacePanel / surfaceControl |
ThemeData |
面板、控件、输入框背景。 |
surfaceControlHover / surfaceControlActive |
ThemeData |
控件 hover 和 pressed。 |
surfacePopup |
ThemeData |
popup、menu、tooltip 容器。 |
surfaceDataHeader |
ThemeData |
表头、分组标题、数据区域 chrome。 |
surfaceNav |
ThemeData |
导航栏、工作区 tab strip、工具边栏。 |
textPrimary / textSecondary / textDisabled |
ThemeData |
主文本、辅助文本、禁用文本。 |
textOnAccent / textOnDanger / textOnSelection |
ThemeData |
实心强调、危险操作和通用选中背景上的文字。 |
borderSubtle / borderControl / borderControlHover |
ThemeData |
弱分隔线、控件边框、控件 hover 边框。 |
borderData / borderDataStrong |
ThemeData |
数据区域边框和强调边框。 |
accentPrimary |
ThemeData |
主操作、选中、高亮。 |
accentSuccess / accentWarning / accentDanger |
ThemeData |
success、warning、danger 强调色。 |
statusSuccessBg / statusWarningBg / statusDangerBg |
ThemeData |
success、warning、danger 状态背景。 |
statusSuccessBorder / statusWarningBorder / statusDangerBorder |
ThemeData |
success、warning、danger 状态边框。 |
selectionBg / selectionStrong / selectionMuted |
ThemeData |
selected、强选中和弱选中背景。 |
focusBorder |
ThemeData |
键盘焦点框。 |
规则:
- 不在组件中写
rgba(24, 144, 255, 1)这类品牌色,除非它位于主题定义文件。 - 不用透明黑白叠加替代状态 token,除非 derive 函数明确处理亮暗主题对比。
- hover 不能比 selected 更强;disabled 不能看起来可点击。
- icon 默认使用文本色或弱文本色;危险、成功、警告图标使用语义色。
- 状态色要在浅色和深色主题下都能被区分。
- 浅色选中背景使用
textOnSelection或resolveSelectionText(),不要默认使用textOnAccent。
尺寸 Token
常见尺寸必须从主题或组件 token 派生:
| 语义 | 推荐来源 | 用途 |
|---|---|---|
controlHeight |
ThemeData |
普通按钮、输入框、下拉框高度。 |
framePadding |
ThemeData |
控件水平 padding。 |
itemSpacing |
ThemeData |
相邻控件间距。 |
frameRounding |
ThemeData |
控件圆角。 |
frameBorderSize |
ThemeData |
控件边框宽度。 |
fontSize / fontFamily |
ThemeData |
正文字号和字体。 |
| component-specific token | 组件级样式 token | tab 高度、rail 宽度、row 高度、icon size。 |
规则:
- 控件高度、tab 高度、row 高度必须稳定,不能因为 hover、selected、文本变化而跳动。
- 图标按钮使用固定命中尺寸;图标本身可小于命中尺寸。
- 分割线和边框优先使用 1px 设备无关线宽;高 DPI 由绘制层处理。
- 紧凑模式应通过 token 派生,不要在组件里散落多个 magic number。
- 组件自然尺寸要由内容和 token 计算,不能依赖上次 paint 结果。
字体 Token
字体层级应保持稳定:
| 层级 | 用途 |
|---|---|
| title | 面板标题、卡片标题、工作区文档标题。 |
| body | 默认正文、表单标签、菜单项、tab 文本。 |
| secondary | 描述、hint、辅助统计。 |
| mono | 代码、日志、对齐数字或调试输出。 |
规则:
- 不用 viewport 宽度缩放字号。
- 不使用负 letter spacing。
- 业务区块和控件标题不能使用 hero 级字号。
- 单行文本默认 ellipsis 或裁剪;多行文本必须有明确最大行数或可滚动容器。
焦点和边框 Token
焦点是交互状态,不是装饰。
- 可键盘操作的组件必须有可见 focus ring。
- focus ring 使用
focusBorder或组件 token,不使用随机强调色。 - focus ring 不应改变组件占位尺寸或让周围内容跳动。
- active pane、selected row、focused cell 是不同语义,不能只靠同一个边框颜色混用。
动效 Token
动画是状态过渡的辅助,不是正确性的前提。
建议默认:
| 动作 | 建议 |
|---|---|
| hover fade | 80-140ms。 |
| press feedback | 即时或 80ms 内。 |
| popup open/close | 可省略;如果存在应短且不影响命中状态。 |
| drag preview | 跟随指针,不做慢动画。 |
规则:
- 动画期间不能改变布局结果。
- 组件被禁用、隐藏或页面关闭后,不应留下仍在运行的视觉反馈。
- 大数据页面应使用轻量的行状态反馈,避免大量常驻动效造成滚动卡顿。
业务主题扩展边界
选择或扩展业务主题值时,依次确认:
- 公开的
ThemeData或组件 options 是否已经表达相同语义。 - 该视觉是否会在多个业务模块复用,而不是单页装饰。
- 自定义后是否仍能正确表达 hovered、focused、selected、disabled 和 error 等状态。
- 深色、浅色和高密度页面下是否仍保持足够的对比度与可读性。
如果公共主题能力不足,应把临时适配集中在业务应用自己的主题层,并提出稳定扩展需求;不要 deep import 或修改框架内部 token 对象。
可组合主题层
现代主题应优先使用 createTheme() 组合以下层,而不是复制整份 ThemeData:
| 层 | 主题字段 | 典型消费者 |
|---|---|---|
| 字体 | typography |
PageHeader、Section、编辑器等宽字体 |
| 动效 | motion |
Button、Checkbox、Tabs、Modal、Drawer、Tooltip、Notification |
| 高程 | elevation |
Modal/Drawer 遮罩、Window/Card 阴影 |
| 编辑器 | editor |
选择背景、反色文字、搜索命中 |
| 图表 | chart |
序列色板、负值、性能时间线 |
| 语法 | syntax |
Tree token、PlainTextEditor token |
主题内的前景色和背景色应使用 contrastRatio() 或 resolveContrastText() 校验。普通文字目标不低于 4.5:1;较大的图形、边框和焦点提示目标不低于 3:1。不要用简单 RGB 明暗阈值代替对比度计算。