867 字
4 分钟
设计令牌与 M3E:统一不等于千篇一律

一个网站刚开始做的时候,组件少,随手写几个颜色值并不会出问题。等到页面变多,问题就会出现:这个卡片的圆角是 12px,那个是 16px;这个标题用 500 字重,那个用 400;两个看起来差不多的灰色,其实是完全不同的值。

本站使用 M3E(Material 3 Expressive)的设计令牌体系,把这类问题提前收进变量里。

令牌不是「多写一层变量」#

--m3e-type-body-large必填font shorthand
500 1.0625rem/1.7

正文级排版。字号、行高和字重一起定义,避免组件里各写各的。

--shape-corner-l可选length
1rem

大圆角容器使用。卡片、弹层和面板保持同一套几何语言。

--m3e-duration-medium可选time
300ms

中等时长动效。配合统一的缓动曲线使用,避免每个组件自己调时间。

::::

这些变量的意义不在于「集中管理」,而在于约束决策范围。当我想给一个卡片加圆角时,不是问「多少像素好看」,而是问「它属于哪个圆角层级」。

排版是最容易失控的部分#

中文和英文的视觉密度不同,同一套字号在两种语言里读起来完全不一样。最初本站的正文偏小,中文显得又细又密;后来我把正文调到 17px,行高提到 1.85,并把正文和标题的字重分别调到 500 和 600,阅读压力才明显下降。

令牌调整前调整后
body-large16px / 40017px / 500
body-medium14px15px
body-small12px13px
title-medium16px / 50017px / 600

字号不是孤立数字,它和行高、字重、字体一起决定阅读感受。

颜色和表面要成对出现#

Material 3 的 surface / on-surface 配对,解决的是「文字放在什么背景上」的问题。只定义一个主色是不够的,还必须定义它对应的可读前景色。

典型的表面配对
.card {
background: var(--surface-container);
color: var(--on-surface);
}
.card--muted {
background: var(--surface-container-low);
color: var(--on-surface-variant);
}

这样切换明暗主题时,不需要在每个组件里写条件判断,变量会自己完成替换。

动效也要有名字#

动效最容易被忽略,但它同样需要约束。本站把常用时长和缓动收进 --m3e-duration-* 与 --m3e-easing-*,并统一尊重 prefers-reduced-motion。

这样做的好处是:当我给一个面板加展开动画时,不需要重新思考「应该用 200ms 还是 400ms」,而是直接选择「短时长」或「中时长」。视觉节奏自然就统一了。

回头看,设计系统真正节省的不是写 CSS 的时间,而是反复做小决定的时间。把那些决定提前做完,才能把注意力留给内容本身。

第 3 篇,共 12 篇本文属于系列

设计令牌与 M3E:统一不等于千篇一律
https://www.ycera.cn/posts/m3e-design-tokens/
作者
初月_Yuechu
发布于
2026-10-22
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取