重构UI
视觉设计不是天赋。它是一小组系统决策,只需做出一次,再加上一套用于创建层次结构的技巧。该技能就是这些系统和这些技巧。
导致UI看起来业余的最大原因是临时随意选择值——这里用17像素,那里用#3B82F6,悬停状态用lighten(5%)。始终从比例出发进行设计。
系统——使用它们,不要重新推导
从这些列表中选择。切勿发明一个不在列表中的值。
间距与尺寸
基准16像素,由其因子和倍数构建:
4 8 12 16 24 32 48 64 96 128 192 256 384 512 640 768
小端紧凑,大端分散。相邻值之间不能小于约25%——这使得选择变得明确。线性的“4的倍数”比例会失败:它无法帮助你在120像素和124像素之间做出决定。
将其用于外边距、内边距、宽度、高度、图标尺寸、边框宽度——所有空间相关的属性。同时固定一小组不透明度值(例如 .05 .1 .2 .4 .6 .8)用于禁用状态、叠加层和悬停着色,而不是每次都凭感觉拖动滑块。与其他比例逻辑相同:一次决定,到处复用。
字体比例
12 14 16 18 20 24 30 36 48 60 72
不是基于比例(如4:5、2:3、黄金比例)构建的模数比例。那些会产生分数像素值,在不同浏览器中四舍五入不一致,并且对于界面密度来说过于稀疏——手工挑选的值,根据它们的视觉感受来选择,效果更好。
单位:仅限 px 或 rem。绝对不要用 em。 em 相对于当前字体大小,因此在一个 1.25em 的父元素内的 .875em 会计算为17.5像素——一个不在你比例中的值。这个比例就会悄然失效。
字重
两个字重就足够了:
- 400 或 500 ——正文和大部分UI文本
- 600 或 700 ——任何需要强调的内容
UI中不要使用低于400的字重。要弱化内容,请使用更浅的颜色或更小的尺寸——绝不要使用更轻的字重。
颜色
你需要比五色调色板生成器提供的多得多的颜色。
- 灰色:8–10个色阶。 几乎所有UI都由灰色构成——文本、背景、面板、边框、表单控件。三到四个色阶总是不够用。从非常深的灰色开始,而不是纯黑色(纯黑色看起来不自然)。
- 主要色:5–10个色阶,一种或两种主要色。
- 强调色:每种5–10个色阶——破坏性红色、警告黄色、正向绿色,以及产品需要区分的任何其他颜色(图表系列、日历事件、标签)。对于复杂的UI来说,10种颜色 × 5–10个色阶是很正常的。
将它们命名为 100(最浅) → 900(最深),基础色为 500。
按此顺序构建色阶: 首先选择 500(对于主要色/强调色,它应该是一个可以用作按钮背景的色阶)。然后找到边缘——900 通常是你的文本颜色,100 是背景色调;一个提示组件会同时使用两者,因此设计一个并从它上面读取两个值。然后按相同方式填充 700 和 300,作为它们相邻色阶的完美折中,接着是 800 600 400 200。
用HSL而不是十六进制书写颜色。 hsl(220, 95%, 34%) 和 hsl(220, 65%, 61%) 在视觉上是相关的;而 #03369E 和 #507DD7 则不然。
绝对不要在运行时使用 lighten() / darken() 生成色阶。 那是你最终得到35种略微不同蓝色的原因。
阴影——五个层级
0 1px 3px hsla(0,0%,0%,.2) /* 几乎不凸起——按钮 */
0 4px 6px hsla(0,0%,0%,.2) /* 下拉菜单 */
0 5px 15px hsla(0,0%,0%,.2)
0 10px 24px hsla(0,0%,0%,.2)
0 15px 35px hsla(0,0%,0%,.2) /* 模态框 */
通过询问“这个元素在Z轴上处于什么位置?”来选择,而不是“什么阴影看起来好看?”。离用户越近 = 获得更多关注。按钮 :active 时缩小其阴影使其感觉被按下;列表项被拾起进行拖拽重排序时增大其阴影则相反——它被理解为“现在在其兄弟元素之上”,并兼作拖拽手势本身的暗示。
这五个阴影是默认值,在任何地方都可以。references/techniques.md 提供了同一比例的两部分细化版本——平行但数值不完全相同(其顶部台阶更重)。当阴影在设计中被突出使用时,使用那个版本;当阴影不是重点时,使用这个版本。不要在一个项目中混合使用两者。
行高和行长
行高与字号成反比,与行宽成正比:
- 小文本 / 宽列 →
1.5到2 - 大标题 →
1就可以了
行长:45–75个字符,即 max-width: 20em–35em。即使其外层容器更宽,这也适用于段落——在一个内容区域中混合宽度看起来更精致,而不是更粗糙。
(em 在这里是正确的——度量应该随其包裹的文本缩放。“绝对不要用 em”的规则仅限于字体比例,因为 em 在嵌套时会复合。不要“修复”这一点。)
圆角半径
选择一个并保持一致。小圆角 = 中性。大圆角 = 有趣。无圆角 = 严肃/正式。在一个界面中混合方形和圆角看起来总是更糟糕。
流程
1. 从功能开始,而不是布局。 不要设计“整个应用”——在你了解产品内容之前,你无法在顶部导航和侧边栏之间做出决定。设计一个真实的功能片段(搜索表单、消息编辑器),让整体布局自然产生。
2. 细节留到后面。 早期忽略字体、阴影和图标。首先以灰度工作——这迫使层次结构来自间距、对比度和大小,而非颜色。在布局可行之后再添加颜色。
3. 不要在低保真上过度投入。 草图、线框和模型是可丢弃的——没有人能使用应用的静态图片。它们存在的目的是探索想法;一旦做出决定,就放弃它们并开始构建真实的东西。
4. 设计最小可用版本,然后构建它。 进行短周期的设计→编码循环。不要暗示你尚未准备构建的功能——一个带有你尚不能交付的附件区域评论框会阻塞整个功能。锦上添花的功能稍后再设计。
5. 通过排除法选择。 当从比例中选择一个值时:先猜你认为正确的那个,然后将其与两侧的相邻值进行比较。两个会明显错误。如果靠外的选项胜出,则以该值为新中间值重新进行比较。
6. 从过多的空白开始,然后再移除。 添加空间直到某些东西看起来不错,得到的是最小值。从慷慨开始然后修剪,得到的是正确的量。密集的UI(仪表盘)是合理的——但这是刻意的决定,而非默认选择。
7. 缩小画布。 在1400像素的画板上设计的小组件往往会铺开,因为有空间可填。从大约400像素开始,先在真实约束下的移动布局进行设计——然后将其带到大屏幕上,只放松那些真正感到局促的部分。你的改动会比预期的少。
层次——最有效的技巧
屏幕上的所有内容都位于一个金字塔中:主要、次要、第三级。当所有内容都在竞争时,UI读起来就像噪音。这才是让设计看起来“经过设计”的原因——而不是样式。
大小不是一切。 仅依赖字号会让你得到太大的主要内容和太小的次要内容。转而使用字重和颜色来承载重点,并保持大小合理。
最多使用三种文本颜色:
- 深色——主要内容
- 灰色——次要内容
- 更浅的灰色——第三级内容(脚注、版权信息)
所有三种颜色都承载真实的正文字体大小文本,因此它们都需要4.5:1的对比度。“更浅的灰色”是指仍能通过该标准的最浅色阶——大约是9阶色阶的中间,而不是浅色端。浅色色阶仅用于禁用状态和大文本。
通过弱化其他内容来强调。 当重要元素无法突出,且没有其他东西可以添加给它时,转而柔化与之竞争的元素。淡化不活跃的导航项;降低侧边栏的背景色,使主要内容凸显出来。
操作: 按层次而非语义设计样式。
- 主要 → 实心,高对比度。通常每页恰好一个。
- 次要 → 轮廓线,或低对比度背景。
- 第三级 → 样式类似链接。
破坏性操作 ≠ 大红色按钮。如果“删除”不是页面上的主要操作,请给它第三级的待遇——然后在确认对话框内部让它成为一个大红主要按钮,因为在那里它确实是主要操作。
标签是最后的手段。 标签: 值 给每条数据相同的权重。大多数数据通过格式($19.99、电子邮件地址)或上下文自我标识。在确实需要标签的地方,将其融入值中(“剩余12件”,而不是“库存:12”),或者将其作为明显的次要内容添加。例外:在规格表风格的页面上,用户搜索标签,此时应强调标签。
平衡字重与对比度。 实心图标在视觉上很重,会盖过旁边的文本——柔化其颜色以补偿。反之亦然:当1像素边框在柔和颜色中太微妙,但变暗后又过于强烈时,保持柔和颜色并增加到2像素。增加字重以修复低对比度;降低对比度以修复过量字重。
视觉层次 ≠ 文档层次。 语义标记和视觉权重是独立的决定。章节标题通常是标签,而非标题——一个16像素的 h1 是可以的,有时标题甚至应该完全隐藏,因为内容本身就能说明问题。
硬性规则
偏离这些规则会产生特定的、可识别的失败结果。
- 绝对不要在彩色背景上使用灰色文本。 灰色在白色上有效,因为它降低了对比度;灰色在颜色上看起来只是脏。降低不透明度的白色看起来褪色且像禁用状态,并且会让图案透过字形显示出来。手工挑选一种带有背景色相的颜色,调整饱和度和亮度。
- 字体比例上绝对不要用
em。 使用px或rem。 - 绝对不要在运行时生成色阶。 事先定义好。
- 绝对不要为不应缩放的东西使用百分比宽度。 侧边栏使用固定宽度;主区域弹性伸展。元素设置
max-width,并且只有屏幕实际更小时才缩小——登录卡片不应在中型屏幕上比大屏幕上更宽。 - 绝对不要在断点间按比例缩放元素。 大元素必须比小元素更快地缩小。一个2.5em的标题搭配14px的移动端正文会计算出35px——太大了;它应该在20–24px之间。同样,按钮的内边距应该随着按钮缩小而按比例变紧,而不是随其字体大小缩放。
- 始终让一个组周围的空间大于组内的空间。 这就是修复“哪个标签属于哪个字段”、拥挤的列表项以及看起来连接到错误段落的标题的问题的方法。模糊的间距是功能性错误,而不仅仅是视觉丑陋。
- 绝对不要将颜色作为唯一的信号。 添加图标、形状或文本提示。对于图表,通过对比度(一种颜色的浅→深色阶)而非色相来区分系列——色盲用户能可靠地读取亮度,但色相则不太行。
- 对比度最小值: 普通文本为4.5:1。3:1的允许值仅适用于大号文本,WCAG将其定义为24px常规字体或18.66px粗体——而不是18px。除非文本真是那么大,否则假设为4.5:1。当白色在颜色上失败时,翻转它:在浅色色调上使用深色文本(参见
references/systems.md)。另外,3:1也适用于非文本内容(WCAG 1.4.11):如果边框是唯一标识控件的东西——输入框轮廓、复选框边缘——它需要与背景有3:1的对比度。仅仅分隔内容的细线则不需要。这是两种不同的标记,不是同一个。 - 绝对不要让图标远离其预期尺寸。 一个16–24px的图标放大到48px会显得笨拙且细节不足。应将其放入一个彩色圆圈内。
参考
assets/tokens.css —— 一个完整、经过对比度验证的起始集合,包含了以上所有内容作为CSS自定义属性:间距、字体、字重、边框宽度、固定不透明度比例、9阶冷灰色阶、9阶主要色阶、三个强调色三元组、五个层级、一个语义角色层(--surface、--text-primary、--action……)和一个暗色模式块,仅覆盖这些角色。复制进去并根据需要调整色相,而不是从头重新推导这些比例。在组件中引用角色,而不是原始色阶——这才是使暗色模式工作的关键。每个文本/表面对在两种模式下经验证均达到≥4.5:1,每个功能性边框经验证达到≥3:1;故意低于阈值的色阶(禁用状态、装饰性分割线、仅用于大文本的色阶)根据标准豁免,并已内联注释。
当工作需要时加载以下内容:
references/systems.md—— 从头构建调色板:选择基础颜色,在亮端和暗端保持饱和度,色相旋转,暖/冷灰色,以及达到对比度比例而不产生难看颜色的两种应急方案。references/diagnose.md—— 症状→修复表格。当任务是改进现有UI而非构建新UI时,首先加载它。references/techniques.md—— 深度和光效模拟、两部分阴影、基线对齐、字间距、跳出默认组件形状以及处理用户上传的图片。