卷 I · 看清· CH 04· 诊断台 深度 4/28

「难看」的七种可名状的病

「难看」是一个没法修的词。它不指向任何具体的东西,所以你只能瞎调。这一章把它拆成七个有名字的毛病——每一个都有一条能在代码里查出来的判据。

挤 散 花 平脏 歪 硬全书路线图

为什么要给它们起名字

第 1 章讲了「每个数要有出处」,第 2 章讲了「每个元素要答一问」,第 3 章讲了「层级可以量」。这三章解决的都是怎么做对

但你实际遇到的场景通常是反过来的:东西已经做完了,看着不对,要找出哪儿不对。

这时候「难看」这个词是有害的,因为它把七种完全不同的问题压成了一个模糊的感受。就像把「肚子疼」当成一种病——它可能是胃、可能是阑尾、可能是你昨晚吃多了,治法完全不同。

这一章要交给你的东西

七个词,每个词配一条能查的判据。判据的标准很硬:你打开代码或者截图,能在一分钟内回答是或否。

不满足这个标准的说法(比如「视觉不够高级」「缺少呼吸感」)一律不收——它们和「难看」一样没用。

七种病

逐个说一遍,顺便交代它们各自归哪一卷管。

挤 —— 什么都贴在一起

判据:相邻元素间距小于 8,并且组内间距和组外间距一样宽

第二句才是关键。单纯「间距小」不一定是病——信息密集的表格就该密。真正的病是组内组外没有区别:所有东西均匀地贴在一起,于是分组信息完全丢失,用户看到的是一堵墙。

归卷 II(第 5、6 章)。

散 —— 什么都离得一样远

判据:所有间距里,最大的那次「跳变比」小于 1.5 倍。

「挤」的孪生兄弟。间距很大,但同样是均匀的大。结果一样:没有分组。第 5 章那台聚类引擎会把这个数字直接算给你看。

归卷 II(第 5 章)。

花 —— 字号、字重、颜色全在变

判据:一屏上超过 4 个字号,或超过 3 个字重。

这就是第 1 章那 18 个字号的直接后果。「花」的感受来源是:每一个层级都动用了全部手段,于是所有层级都在喊,谁也压不住谁。

归卷 III(第 9、12 章)。

平 —— 看不出哪个重要

判据:眯眼之后,权重最高的两个相差不到 20%。

「花」的反面,但同样致命。所有东西都是中等重量,于是眼睛没有落点,只能从左上角开始逐行扫描——那是在读文档,不是在用界面。

归第 3、12 章。

脏 —— 灰得发糊、颜色发脏

判据:正文对比度低于 4.5:1;或者一组灰色的色相在乱跳(有的偏蓝有的偏黄)。

「脏」有两个来源,而且都很好查。一是对比度不够——这是能算出确切数字的(第 14 章)。二是中性色不成体系:你的 #9E9E9E#8A8A8A#757575 各来自不同的地方,色相互相打架。

归卷 IV(第 13、14 章)。

歪 —— 看着没对齐但说不出哪儿

判据:元素边缘不落在 8 的倍数上;或者图标是按几何中心居中的。

第二条是那个让人抓狂的:明明代码里写的是 Alignment.Center,看上去就是偏了一点。答案是几何中心不等于视觉中心——第 7 章会把播放三角形的质心精确算出来给你看(往右挪 16.7%,24px 的图标就是 4px)。

归卷 II(第 6、7 章)。

硬 —— 状态切换很生硬、点了没反应

判据:可点元素没有 pressed 态;或者转场时长是 0,或者超过 500ms。

「硬」是唯一一个静态截图看不出来的病,所以它最容易漏。而它对「像样」的杀伤力很大:一个点下去毫无反馈的按钮,会让人以为 App 卡了。

归卷 V(第 18、20 章)。

这七个词怎么用

用法很简单:觉得不对的时候,按顺序问一遍。

顺序为什么排这个位置
1挤 / 散?间距问题最常见,也最好改——改完往往其他问题跟着消失
2平?层级是骨架。骨架不对,改颜色改字号都是白费
3花?和「平」是一对,一起判断:是没层级,还是层级太多
4脏?能算出确切数字,最容易变成自动化检查
5歪?通常是最后收尾的活
6硬?静态图看不出来,必须真机点一遍
为什么顺序是这个

因为前面的病会伪装成后面的病

间距乱的界面看起来会「脏」,于是你去调颜色——调不好,因为病根不在颜色。层级不对的界面看起来会「花」,于是你去减字号——减完变成「平」,因为你减错了地方。

按这个顺序查,能避免绝大部分的白费功夫。

一个反例:什么不是病

为了让这七个词有边界,说几个不算病的东西:

  • 信息密度高——密不是病。财务软件、代码编辑器、航班信息屏都该密。密而不乱靠的是分组和对齐,不是留白。
  • 用了系统默认样式——默认样式通常是对的。「看起来像原生 App」不是缺点,那是几百人打磨过的结果。
  • 没有插画、没有渐变、没有动效——这些是可选项,不是及格线。一个只有文字和按钮但间距对齐颜色全对的界面,比一个满是渐变但间距乱的界面像样得多。
  • 和竞品长得像——同一类产品的用户有同一套预期。刻意做得不一样,代价是用户要重新学。
最贵的一个误判

把「不够特别」当成病来治。

你的界面看起来平平无奇,这通常说明它是对的。用户打开一个 App 不是来欣赏的,是来办事的——办完事之后他不该记得你的界面长什么样。

「像样」的天花板不是「惊艳」,是「顺手到没人提起」。这是这本书唯一一处需要你调整期待的地方。

七条里有五条可以变成自动化检查。现在先看形式,第 24 章给完整版:

// 脏:对比度。可以写成真正的单元测试
@Test
fun bodyTextMeetsAA() {
    val ratio = contrastRatio(
        MaterialTheme.colorScheme.onSurface,
        MaterialTheme.colorScheme.surface
    )
    assertThat(ratio).isAtLeast(4.5)
}

// 硬:触摸目标。Compose 测试里能直接量
composeTestRule.onNodeWithTag("like")
    .assertHeightIsAtLeast(48.dp)
    .assertWidthIsAtLeast(48.dp)

// 花:字号字面量。一条 lint 规则就够
// 禁止 UI 层出现裸的 .sp / .dp,只允许 MaterialTheme.* 和 Spacing.*

剩下两条(「平」和「状态不只靠颜色」)目前只能靠眼睛——但也只剩两条了。

卷 I 结束

到这里,你手上有了四样东西:

一个总账110 个随手定的数 → 34 个
一把尺这是什么 / 我能做什么 / 现在怎么了
一台仪器眯眼 = 高斯模糊,层级可积分
一套词汇挤 散 花 平 脏 歪 硬

接下来六卷,一卷关一类自由度。下一卷是距离——这本书里性价比最高的一卷,因为间距是所有维度里最便宜改、见效最快的一个。

本章关掉的自由度本章 7 条 · 累计 13 / 78
  • ——组内间距 : 组外间距至少 1 : 2,不再凭感觉留白。
  • ——间距必须有明显跳变(≥ 1.5 倍),均匀等于没分组。
  • ——一屏字号 ≤ 4 个、字重 ≤ 3 个。
  • ——眯眼后前二权重必须拉开 20% 以上。
  • ——正文对比度 ≥ 4.5:1,灰色全部从同一条中性阶取。
  • ——边缘落在 8 的倍数上,图标按视觉质心补偿。
  • ——每个可点元素有 pressed 态,转场时长取 token 且 ≤ 500ms。