卷 VI · 交付· CH 24· 全书检查表 深度 24/28

出门前的检查表

二十三章、六十七个关掉的自由度,压成一页。用法是做完之后打开,不是边做边看。

15 条11 条能自动化没有一条是「好不好看」

注意这张表里没有一条是「好不好看」

全是可以回答是或否的问题。这就是这本书从第 1 章开始一直在做的事:把审美问题换成工程问题。

换不掉的那四条(层级、留白归属、一个层级几个手段、眯眼验收),我也没硬凑成判据——它们确实要靠眼睛。但只剩四条了,四条是人真的会做的量。

把能自动化的搬进 CI

十一条里,有五条几乎是白送的。这五条加起来不到一百行代码,写完这一辈子不用再管:

// ① 对比度 —— 覆盖「脏」的全部
@Test fun everyOnColorMeetsAA() { /* 第 14 章那二十行 */ }

// ② 触摸目标 —— 覆盖一半的「硬」
@Test fun iconButtonsMeetTouchTarget() { /* 第 19 章 */ }

// ③ 字面量 lint —— 覆盖「花」和大半个「挤/散」
//    禁止 UI 层出现裸的 .dp / .sp / Color(0x…) / 时长数字

// ④ 状态穷尽 —— 编译器免费送
sealed interface UiState { /* 第 20 章。when 漏分支就编译不过 */ }

// ⑤ 行长 —— 一行断言
@Test fun bodyTextStaysReadable() {
    val chars = contentWidthDp / (0.499f * bodyFontSizeSp)
    assertThat(chars).isIn(Range.closed(45f, 75f))
}

全书六十七条,按卷排

检查表是压缩版。要查具体某一条的出处,回这张表:

关掉了一句话
I 看清13把「难看」换成七个能查的词
II 距离11间距是语法:组内 : 组外 ≥ 1 : 2,值落 8 的倍数,由容器给
III 字10七级阶梯、一屏 ≤ 4 级、行长 45–75 字符、一个层级一两个手段
IV 色12一个种子长出全部;写角色不写色值;对比度是算的
V 手12动效解释因果;可点区 ≥ 48dp;状态有 14 格不是 3 格
VI 交付9token 三层、插槽而非参数、抄限检三步
合计 67 条

如果你只记三句话

你不缺审美,你缺的是出处。界面难看不是因为你选的颜色不好,是因为这一屏上有一百一十个当时随手定的数。

设计师不是每次都选得比你好,是他们不每次都选。先定十几个数,之后每写一个界面只从里面取。

你能把规则写成代码。设计师靠眼睛和纪律维持一致,你可以靠 lint、类型系统和 CI。纪律会随时间衰减,CI 不会。

现在按一下 M

这本书从第 1 章起就一直邀请你做一件事:M 键,检查它自己。

红线浮出来之后你会看到:每两个区块之间的间距是多少、落没落在 8 的格子上、每段文字的字号行高是几、文字和背景的对比度是几比几。这些数字是当场从 DOM 量的,不是写死的。

如果它哪里没守自己写的规矩,你现在有能力当场指出来——而且能说出是哪一条。

那就是这本书想给你的全部。

还有一卷

主线到这里结束了。后面还有一卷 补卷「表面」(第 25–28 章),讲这本书前面刻意绕开的第三个维度:阴影、边框、图像,以及一个反直觉的工作法——先做灰度,颜色最后加

它不是主线的一部分,但如果你已经把前 24 章跑通了,那四章会让界面从「不难看」再往上抬一档。

本章关掉的自由度本章 0 条 · 累计 67 / 78
  • 这一章不关新的自由度——它把前二十三章关掉的 67 条压成了一页能在两分钟内跑完的表。