目标是做出一套“开发可直接落地”的按钮组件:同一个组件里包含不同尺寸(S/M/L)、不同类型(Primary/Secondary/Ghost)、不同状态(Default/Hover/Pressed/Disabled/Loading),并且在文案变长、左右留白变化时仍然保持对齐与间距一致。
打开 Figma 新建一个页面,先写下按钮的基础规范(建议放在页面左上角当成“组件说明”):
1) 尺寸:S=28px,M=36px,L=44px(高度可按你的项目调整,但务必固定)。
2) 内边距:左右 padding 建议从 12/16/20 起步(S/M/L 逐级增加)。
3) 圆角:例如 8px(全项目统一)。
4) 字体:例如 14/16/16(S/M/L),字重 500/600。
为什么要先定?因为 Variants 的价值就是“所有组合都遵循同一套规则”。规范不清楚,后面会越做越乱。
新建一个 Frame 作为按钮容器,按以下设置:
1) 选中 Frame → 按 Shift+A(Auto Layout)。
2) 方向:Horizontal;间距:8(用于 icon 与文字之间)。
3) Padding:左右 16,上下 8(先按 M 尺寸做)。
4) 对齐:Vertical Center。
5) 宽度:Hug contents;高度:Fixed(例如 36px)。
在里面放一个 Text(按钮文案),可选再放一个 Icon(例如 16x16)。此时你已经得到一个“文案变长也能自适应”的按钮结构。
选中按钮 Frame → Create component。推荐内部命名:
1) 容器:Button/Container
2) 图标:Button/Icon(可隐藏)
3) 文案:Button/Label
命名的意义是为了后续交付与维护,尤其是多人协作时,组件的结构要一眼能看懂。
建议从 3 个维度开始,够用且不炸裂:
1) type:primary / secondary / ghost
2) size:s / m / l
3) state:default / hover / pressed / disabled / loading
先只做 type=primary 的一套完整状态,再复制扩展到 secondary/ghost,会更稳。
在 Figma 中选中组件 → Add variant(或 Combine as variants)。然后按下面方式命名属性(关键):
1) 不要用中文属性名;保持小写;用清晰的名词:type、size、state。
2) 值用短词:primary、secondary、ghost;s/m/l;default/hover/pressed/disabled/loading。
3) 组件集名称建议:Button(别带多余前后缀)。
好处:你在右侧属性面板里切换组合会非常顺手,开发同事也更容易理解。
在 state 维度里,尽量只改视觉 token:
1) default:正常背景/描边/文字色。
2) hover:背景加深或描边加深(不要改尺寸)。
3) pressed:再加深一点或加内阴影(仍不改尺寸)。
4) disabled:降低对比度,文字与背景统一变灰,同时把组件的交互提示(如 hand cursor)去掉(原型中可不设置)。
5) loading:显示一个 loading icon,并把 Label 可选隐藏或改为“加载中”。建议用一个布尔属性 icon=true/false 也可以,但为避免属性爆炸,这里直接在 state=loading 里处理即可。
如果你的按钮会出现在固定宽度的卡片或表单里,你可能需要两种宽度策略:
1) 默认:Hug contents(最常见)。
2) Block 按钮:Fill container(占满父容器)。
做法:在组件集里增加一个 width 属性(hug / fill),或者在交付时提供一个单独的 BlockButton 组件。小团队建议用第二种(更简单)。
交付不需要写长文档,但建议写 6 行以内的“可执行说明”:
1) Button:type/size/state 取值范围
2) 高度:S/M/L 的固定高度
3) padding:左右/上下间距
4) icon:有无图标、尺寸与间距
5) disabled:颜色与交互规则
6) loading:出现时文案是否保留
1) Variants 维度过多导致组合爆炸:先做 3 维,跑通再扩展。
2) 不同尺寸改了字体但忘了改 padding:最终视觉会不一致。
3) Hover/Pressed 改了阴影但没统一 token:组件集会变得不可控。
4) 命名含糊(如 style1/style2):后续维护成本极高。
1) 文案从 2 个字到 10 个字,按钮都保持居中且间距一致。
2) 切换 size 时,高度与字体匹配。
3) 切换 state 时,只发生颜色/显示变化,尺寸不跳。
4) 开发能从右侧属性面板一眼看懂 type/size/state。