Communitygithub.com

s0xDk/refactoring-ui-skill

使用《重构UI》(Wathan & Schoger)中的具体规则来设计和改进用户界面——包括约束的间距/字体/颜色/阴影比例、通过字重和颜色而非字体大小建立的视觉层次、以及通过模拟光照实现的深度。适用于构建或样式化任何UI(网页、应用、仪表盘、落地页、组件),选择字号、间距、颜色、阴影或圆角时,设计调色板或设计令牌时,以及当有人说UI“看起来不对劲”、“看起来很业余”、“感觉杂乱/平淡/未完成”,或要求“让它更好看”时。

refactoring-ui-skill 是什么?

该技能基于《重构UI》一书的核心原则,提供了一套系统化的UI设计方法,帮助开发者摆脱随意选择值的习惯,建立一致的设计系统。它包含了间距与尺寸、字体、颜色、阴影、行高与行长、圆角等关键设计元素的预定义规则,并提供了具体的选择流程和技巧。该技能强调通过空间、对比度和颜色建立视觉层次,而非仅依赖字号。适用于任何需要构建或优化UI的项目,包括Web应用、移动应用、仪表盘、组件等,尤其擅长解决UI看起来“不专业”或“不协调”的问题。您可以在支持markdown技能的AI开发工具(如Claude Code、Cursor、Codex等)中直接使用该技能,通过引用其规则和参考文件来指导设计决策。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add s0xDk/refactoring-ui-skill

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

重构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 是可以的,有时标题甚至应该完全隐藏,因为内容本身就能说明问题。


硬性规则

偏离这些规则会产生特定的、可识别的失败结果。

  1. 绝对不要在彩色背景上使用灰色文本。 灰色在白色上有效,因为它降低了对比度;灰色在颜色上看起来只是脏。降低不透明度的白色看起来褪色且像禁用状态,并且会让图案透过字形显示出来。手工挑选一种带有背景色相的颜色,调整饱和度和亮度。
  2. 字体比例上绝对不要用 em。 使用 px 或 rem。
  3. 绝对不要在运行时生成色阶。 事先定义好。
  4. 绝对不要为不应缩放的东西使用百分比宽度。 侧边栏使用固定宽度;主区域弹性伸展。元素设置 max-width,并且只有屏幕实际更小时才缩小——登录卡片不应在中型屏幕上比大屏幕上更宽。
  5. 绝对不要在断点间按比例缩放元素。 大元素必须比小元素更快地缩小。一个2.5em的标题搭配14px的移动端正文会计算出35px——太大了;它应该在20–24px之间。同样,按钮的内边距应该随着按钮缩小而按比例变紧,而不是随其字体大小缩放。
  6. 始终让一个组周围的空间大于组内的空间。 这就是修复“哪个标签属于哪个字段”、拥挤的列表项以及看起来连接到错误段落的标题的问题的方法。模糊的间距是功能性错误,而不仅仅是视觉丑陋。
  7. 绝对不要将颜色作为唯一的信号。 添加图标、形状或文本提示。对于图表,通过对比度(一种颜色的浅→深色阶)而非色相来区分系列——色盲用户能可靠地读取亮度,但色相则不太行。
  8. 对比度最小值: 普通文本为4.5:1。3:1的允许值仅适用于大号文本,WCAG将其定义为24px常规字体或18.66px粗体——而不是18px。除非文本真是那么大,否则假设为4.5:1。当白色在颜色上失败时,翻转它:在浅色色调上使用深色文本(参见 references/systems.md)。另外,3:1也适用于非文本内容(WCAG 1.4.11):如果边框是唯一标识控件的东西——输入框轮廓、复选框边缘——它需要与背景有3:1的对比度。仅仅分隔内容的细线则不需要。这是两种不同的标记,不是同一个。
  9. 绝对不要让图标远离其预期尺寸。 一个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 —— 深度和光效模拟、两部分阴影、基线对齐、字间距、跳出默认组件形状以及处理用户上传的图片。

相关技能