"设计系统"听起来像是有专门团队和文档网站的大公司才需要的东西。但小团队其实更需要它:两个设计师、三个开发者,每一处不一致都要靠人手一遍遍修。诀窍是做一个小的设计系统,并按正确的顺序来做。
小型设计系统到底是什么
三层结构,起步只需要前两层:
- Token(设计令牌)——有名字的设计决策:颜色、字号、间距、圆角、阴影、动效。
- 组件——由这些 Token 构成的可复用部件:按钮、输入框、卡片。
- 模式和规范——组件如何组合:表单、空状态、页面布局。等你发现自己在反复解释同样的事情时,再把它写下来。
大多数团队从第二层开始,在 37 种略有差别的灰色之上做出一套漂亮的按钮库。请从 Token 开始。
第一步:Token
颜色
分两级定义。基础(primitive)Token 是色板;语义(semantic)Token 说明颜色用来做什么:
:root {
/* Primitives */
--blue-500: #0777d2;
--blue-600: #0563b0;
--gray-50: #f8f9fa;
--gray-900: #111418;
--red-600: #d92d20;
/* Semantic — components only use these */
--color-bg: #ffffff;
--color-surface: var(--gray-50);
--color-text: var(--gray-900);
--color-text-muted: #5b6370;
--color-primary: var(--blue-500);
--color-primary-hover: var(--blue-600);
--color-danger: var(--red-600);
--color-border: #e3e6ea;
}
[data-theme='dark'] {
--color-bg: #0d1117;
--color-surface: #161b22;
--color-text: #e6edf3;
--color-border: #30363d;
}组件只引用语义 Token。这样一来,深色模式、品牌升级或者给客户做白标,都只需要改一个文件。
顺便检查对比度:正文文字与背景的对比度至少要 4.5:1(WCAG AA),大号文字至少 3:1。
字体排版
选一到两种字体,以及六到八级字号。使用模数比例(每一级约为上一级的 1.2–1.25 倍)能让节奏保持一致:
:root {
--text-xs: 0.75rem;
--text-sm: 0.875rem;
--text-base: 1rem;
--text-lg: 1.25rem;
--text-xl: 1.5rem;
--text-2xl: 2rem;
--text-3xl: 2.75rem;
--leading-tight: 1.15;
--leading-normal: 1.6;
}间距、圆角、阴影、动效
一套 4 或 8 像素的间距尺度(4, 8, 12, 16, 24, 32, 48, 64),两三种圆角,两三种阴影,两三种时长加一条缓动曲线。每一个不在尺度上的值,都意味着有人要重新做一次决定。
在 Tailwind CSS 中
如果你用 Tailwind,主题配置就是你的 Token 文件。把它指向 CSS 变量,让同一套 Token 同时驱动两边:
export default {
theme: {
extend: {
colors: {
bg: 'var(--color-bg)',
surface: 'var(--color-surface)',
text: 'var(--color-text)',
muted: 'var(--color-text-muted)',
primary: { DEFAULT: 'var(--color-primary)', hover: 'var(--color-primary-hover)' },
danger: 'var(--color-danger)',
border: 'var(--color-border)',
},
},
},
}第二步:最先做的十个组件
它们覆盖了大多数产品页面:
- 按钮——主要、次要、幽灵、危险;不同尺寸;加载和禁用状态
- 文本输入框——带标签、提示和错误信息
- 下拉选择 / 组合框
- 复选框、单选框和开关
- 卡片——几乎所有东西的容器
- 弹窗 / 对话框——带焦点锁定,按 Esc 关闭
- Toast 提示——用于确认和报错
- 标签页(Tabs)
- 徽标 / 标签
- 空状态——一个图标、一行文字、一个操作
不要从零开始做无障碍:Radix UI、React Aria 或 Headless UI 这类无样式组件库已经处理好了焦点、键盘导航和 ARIA,你只需用自己的 Token 给它们加样式。shadcn/ui 是一个流行的起点,它把基于 Radix 的组件复制到你自己的代码库中,由你完全掌控。
每个组件都需要它的状态
演示和产品的区别就在于状态。每个组件都要设计并实现:默认、悬停、焦点(要清晰可见!)、按下、禁用、加载、错误和空状态。焦点状态最常被遗忘——而键盘用户恰恰依赖它。
第三步:让 Figma 和代码保持同步
- 两边用同样的名字。 如果 Figma 叫
color/text/muted,代码里叫--gray-500,它们迟早会分道扬镳。在 Figma Variables 中使用与 Token 文件相同的语义名称。 - 数值只有一个来源。 小团队可以直接约定以代码为准,Token 变化时更新 Figma 变量。大一些的团队会把变量导出为 JSON,再用 Style Dictionary 或 Tokens Studio 生成 CSS。
- Figma 组件与代码组件的属性一一对应。 Figma 中的变体
size=sm, variant=secondary应该对应<Button size="sm" variant="secondary">。
第四步:只记录你反复说的东西
文档不需要是一个网站。代码仓库里的一页说明——Token 列表、每个组件的截图和几条规则("每个页面只有一个主按钮"、"破坏性操作需要二次确认")——就足够了。每当你在评审中第二次解释同一件事,就加一条规则。
最常见的错误
- 变体太多。 五种谁也分不清的按钮样式。从三种开始。
- 硬编码的值又偷偷回来了。 一条 lint 规则或代码评审清单中的一项("
tokens.css之外不准出现十六进制颜色值")能让系统保持诚实。 - 设计还没有页面需要的组件。 等到第二个页面需要时再做组件,而不是提前做。
- 把设计系统当成已完成的东西。 它是一个产品,用户是你自己的团队。每隔几个月回头看看。
需要多长时间?
对于一个小型产品,第一版——Token、带完整状态的十个组件、Figma 变量和一页说明——大约需要一到三周的设计加开发时间。第一次在一个下午内做完一个新页面,或者用一天时间上线深色模式时,它就回本了。
从零开始,还没有 logo 和品牌?先做那个——见创业公司上线时真正需要的品牌形象。

