这篇记录我现在在设计系统里使用 Figma Variables 的一套设置方式,主要方便自己以后继续扩展组件、主题和 token 时查阅。
目前我会把变量拆成几个独立集合。这样在右侧面板里更容易找到,也能避免不同用途的值混在一起。
| 集合 | 类型 | Scope | 用途 | 主要绑定位置 |
|---|---|---|---|---|
| Primitives | COLOR | — | 原始色板,例如 ocean/50~900 | 不直接绑定组件,由 Semantic 引用 |
| Semantic | COLOR | TEXTFILL / SHAPEFILL / FRAMEFILL / STROKECOLOR 等 | 语义颜色,例如 text/、icon/、bg/、border/ | 文字、填充、背景、描边 |
| Text | STRING | ALL_SCOPES | 文字内容 token | Text characters |
| Radius | FLOAT | CORNER_RADIUS | 圆角 | Corner radius |
| Spacing | FLOAT | WIDTH_HEIGHT / GAP | 间距、内边距 | Padding、item spacing、gap |
| Border | FLOAT | STROKE_FLOAT | 描边粗细 | Stroke weight |
| Opacity | FLOAT | OPACITY | 图层不透明度 | Appearance → Opacity |
| Size | FLOAT | WIDTH_HEIGHT | 组件高度 / 宽度 | minHeight / minWidth 等尺寸属性 |
我会按用途拆集合。即使 Radius、Spacing、Border、Opacity 都是 FLOAT,也会分开管理。这样后面看变量名和绑定位置时更直观。
Scope 会直接影响变量在右侧面板里的可见位置。
例如,同样是 FLOAT:CORNER_RADIUS 只出现在圆角相关字段;GAP 出现在间距相关字段;STROKE_FLOAT 出现在描边粗细相关字段。
Scope 设得准确,变量面板会干净很多。设计系统规模一大,如果圆角、间距、尺寸、描边都同时出现在同一个变量选择器里,很快就会难找。
Plugin API 里的 setBoundVariable 可以绕过 Scope 强制绑定。我现在不会这样做。绑定虽然能成功,Figma UI 里却可能无法正常看到和管理,后续检查和维护会比较麻烦。
我会把 Scope 当成实际使用范围来设置,让设计师在对应属性里只看到合理的变量。
Spacing 和 Radius 我都会做成非线性梯度。小尺寸区间更密,大尺寸逐渐拉开。
Spacing. 目前使用:
0, 2, 4, 6, 8, 10, 12, 16, 20, 24, 32, 40, 48, 56, 64, 80命名大致按尺寸递增:None → 2XSmall → XSmall → Small → Medium → Regular → Large → XLarge → 2XLarge ...
小间距在 UI 里使用频率更高,所以 2、4、6、8、10、12 这些档位会保留得比较细。到 24 以上,档位可以逐渐拉开。
Radius. 目前使用:
0, 1, 2, 4, 6, 8, 10, 12, 16, 20, 24, 32, 99999999 用作 Full,适合胶囊按钮、圆形标签等完全圆角的情况。命名可以按:None → XSmall → Small → Regular → Medium → Large → XLarge → Huge → Full。
Border. 描边目前只保留几档常用值:
0 = None
1 = Thin
1.5 = Regular
2 = Thick如果产品里没有 3px、4px 的固定使用场景,我不会为了把梯度做完整专门补出来。
Opacity. 直接用百分比整数:
5, 8, 10, 20, 30, 40, 50, 60, 70, 80, 90命名也直接对应:5% → 8% → 10% → 20% ... Figma Appearance 里的 Opacity 字段使用百分比,所以变量值写 10、20,不是 0.1、0.2。
Size. 我会按真实组件尺寸来建。目前主要用于按钮高度:
24 = XXS
28 = XS
32 = SM
36 = MD
40 = LG
48 = XLSize 不需要提前覆盖所有可能值。组件真正需要新的固定尺寸时再补就可以。
颜色目前分两层:
Primitives → Semantic → ComponentPrimitives 保存原始色值,例如 ocean/50 到 ocean/900。这一层只表示色板本身。
Semantic 按使用场景命名,例如 text/primary、text/secondary、icon/primary、bg/default、bg/brand、border/default。Semantic 引用 Primitives,组件再绑定 Semantic。
例如一个品牌色按钮,组件里绑定的是 bg/brand,而 bg/brand 当前可以指向 ocean/600。以后品牌色调整,只改 Semantic 的引用即可。
Light / Dark Mode 也可以用同样的方法处理。组件继续使用 text/primary、bg/default 这些语义变量,不需要逐个组件改颜色。
所以组件层我会尽量避免直接绑定 ocean/600 这样的原始色值。
这两个都会让画面变透明,但使用位置不同。
| Layer Opacity | Paint Opacity / Color Alpha | |
|---|---|---|
| 位置 | Appearance 区域 | Fill / Stroke 色值内部 |
| 影响范围 | 整个图层以及所有子元素 | 只影响当前 Fill / Stroke |
| 常见场景 | Disabled、淡入淡出、整个组件降低视觉权重 | 半透明背景、遮罩、叠加层 |
| 变量方式 | Opacity 集合里的 FLOAT | COLOR 变量自身的 Alpha 通道 |
我一般这样判断:Disabled 状态下整个组件临时变淡,用 Layer Opacity;Overlay、半透明背景这类颜色本身长期带透明度的情况,把 Alpha 放进颜色变量里。
这个区分在组件嵌套时尤其有用。Layer Opacity 会连子元素一起影响,如果本来只想让背景半透明,结果把文字和图标也一起压低,就会出现额外的透明度叠加。
目前这套结构已经能覆盖我在设计系统里的大部分变量使用。后续如果增加新的组件类型或主题,再按实际需求继续补集合和值。