这篇用“按钮组件”做一条完整链路:从结构、自动布局、变体,到用变量把颜色/圆角/间距统一起来。做完后你会得到一个能覆盖常见场景(主按钮/次按钮/危险/幽灵/禁用/加载)的可复用按钮,并且能在设计系统里长期维护。
在动手搭组件之前,先把按钮当成一个系统里的“动作触发器”来看:它要告诉用户这是可点击的、点击后会发生什么、当前是否可用。建议把按钮拆成 3 层:容器(背景与边框)、内容(文字/图标)、状态覆盖(hover/pressed/focus/disabled/loading)。这样后面做变体时,不会把样式和结构搅在一起。
常见坑:把不同尺寸/不同样式做成完全不同的结构;或者把图标当成装饰随便塞,导致文字居中不稳、间距不一致、改一处全崩。
新建一个按钮 Frame,开启 Auto Layout。方向一般为横向,居中对齐。建议最小结构是:左图标(可选)+ 文案 + 右图标(可选)。把三个元素都放进同一个 Auto Layout 容器里,间距用统一变量控制。
Auto Layout 的关键不是“让它自动”,而是“让它有规则”: 1)Padding 固定(通过变量),按钮高度由 padding + 字号决定; 2)内容对齐永远居中; 3)图标尺寸固定,文字不挤压图标; 4)按钮宽度按内容 Hug,必要时再提供一个 Fill 的用法。
建议的变体维度(不要一上来就堆太多): - type:primary / secondary / ghost / danger - size:sm / md / lg - state:default / hover / pressed / disabled / loading - icon:none / left / right / both(也可以用布尔属性替代)
变体的好处是:同一个结构下切换属性就能得到不同外观,不需要复制粘贴一堆组件。注意 state 维度要克制:如果团队还没有严格的交互规范,可以先只做 default/disabled,等产品节奏稳定再补 hover/pressed。
变量是让设计系统可维护的关键。建议至少建立三类变量:
1)Color tokens(语义色) 比如:btn/primary/bg、btn/primary/text、btn/primary/border;btn/secondary/bg……这样当品牌色更新或主题切换时,只改变量不改组件。
2)Space tokens(间距) 比如:space/2、space/3、space/4,对应 8px、12px、16px。按钮的 horizontal padding、图标与文字间距都引用这些 token,保证全站一致。
3)Radius/Stroke tokens(圆角与描边) 比如:radius/s、radius/m;stroke/1。按钮的圆角和边框宽度一处统一,避免不同页面出现“差1像素”的尴尬。
禁用(disabled)不是简单把透明度拉低。更稳的做法是:背景/文字/边框分别切到 disabled token,保持对比度和可读性;同时把 hover/pressed 的反馈彻底去掉。
加载(loading)建议用一个固定尺寸的 spinner(或替代图标)占位,避免按钮宽度跳动。最常见的体验问题是:点击后文字消失导致按钮突然变窄,页面布局抖动。解决方法:loading 状态里保留文字但设为透明、或用同宽占位。
组件命名建议简洁、可搜索:Button / Button.Icon / Button.Group。变体属性用小写英文或统一格式(primary、secondary、ghost;sm、md、lg;default、disabled、loading)。 在组件描述(De ion)里写清楚: - 什么时候用 primary/secondary - loading 的触发规则 - 是否允许图标单独成按钮(Icon Button) - 最小可点击区域(例如 44px)
你可以用下面的 checklist 作为发布前自测:
1)同一尺寸下,不同 type 的内边距一致; 2)带左图标/右图标时,文字仍然视觉居中; 3)Hug 内容时宽度不会抖,Fill 宽度时两端 padding 正常; 4)禁用状态不出现 hover/pressed; 5)loading 状态不改变布局; 6)颜色/圆角/间距都来自变量,而不是手填数值。
按钮是设计系统里最“高频、最容易出错、最能暴露规范问题”的组件。把按钮做对了,你的颜色体系、间距体系、命名体系、交互状态几乎都能顺着立起来。后续再做输入框、标签、弹窗时,就会顺很多。