像样
你不缺审美,你缺的是出处。
让一个开发,一个人,也能做出像样的界面。
你写完一个界面,感觉「不太对」,但说不出哪里不对。于是你换了个蓝色,加了点阴影,把圆角从 8 改成 12——还是不对。
问题从来不在那个蓝色。把一份真实业务代码那样的界面声明丢进计数器:六个界面、44 个元素,里面有 18 个不同的字号、24 种间距、12 种圆角、25 个颜色——一共 110 个当时随手定的数。
你能说出 13.5sp 和 14sp 的分别吗?用户也不能。但他能感觉到这一屏「有点脏」。
设计师不是每次都选得比你好,是他们不每次都选。他们先把值定下来,之后每写一个界面,只从那几个值里取。这本书做的就是这件事:把界面上的自由度一个个关掉,关到最后只剩 34 个。
而你有一样设计师没有的东西:你能把规则写成代码。他们靠眼睛和纪律维持一致,你可以靠类型系统。
这本书自己就是范例
既然讲设计,这本书必须能被检查。所以它把自己的构造公开了:
- 正文浮在一块白画板上,宽屏时左边有一条真的刻度尺,8 一小格、48 一大格;
- 随便翻到哪一章,按 M 键,整页浮出红线标注——每两个区块之间的间距是多少、落没落在 8 的格子上、每段文字的字号行高、文字和背景的真实对比度是几比几;
- 这些数字是当场从 DOM 量的(
getBoundingClientRect+getComputedStyle,再把颜色喂进 WCAG 公式),不是写死的。你可以拿这本书自己做一次 UI 审查。
还有一件事:这本书的卷色不是挑的。它们是书里那台 OKLCH 引擎生成的——同一个亮度 L = 0.52、同一个目标彩度 C = 0.125,只有色相在动。其中黄和青塞不下 0.125,被夹到了各自的上限,因为 sRGB 的色域不是个球。这件事本身就是第 13 章的教材。
第七卷是补卷,取了同一个 L 但把彩度压到 0.02——全书唯一一个近乎无彩的卷色。它讲的就是表面。
九台真引擎
这本书里没有一个数是我拍脑袋写的。所有对比度、色阶、行盒、聚类、模糊、弹簧、Fitts 全部现场算,验证器会把正文里手写的数字和引擎的返回值逐个对一遍。其中两台值得单独说:
第 15 章那台调色板引擎,是 Material 3 取色空间 HCT 的完整实现(CAM16 色貌模型 + CIE L* 亮度 + 色域边界求解器)。它和 Google 的 material-color-utilities 对过答案:
- 6000 组随机 (H, C, T) → sRGB,6000 个逐位相同;
- 8 个种子色 × 5 条色阶 × 24 个色调,共 960 格全中;
- 而且里面那两个关键矩阵不是抄 Google 源码里的常数,是从 M16 × sRGB→XYZ 现算的——算出来和它对到小数点后 15 位。
第 10 章讲「设计稿上对不上的那几个像素」,用的不是博客上抄来的数,是 scripts/probe-fonts.mjs 直接解析字体文件二进制的 head / hhea / OS/2 / hmtx 表。Roboto 取的是 Android Studio 里 layoutlib 用的那一份——也就是 Android 预览真正拿来排版的文件本身。
于是「16sp 的 Roboto 默认行高 18.75px,开着 includeFontPadding 会变成 21.10px,上面多 1.922 下面多 0.430」这句话里的每个数,都能追到那个文件的某几个字节。
那本书(Adam Wathan & Steve Schoger,2018)是「写给开发者的设计书」这个品类的原型,这本书从它那儿拿了不少东西,都在正文里标了出处:标签是最后手段(第 2 章)、从太多留白开始往回收(第 5 章)、别在彩色背景上用灰字(第 16 章)、无障碍不等于难看(第 14 章)、一切都有它该有的尺寸(第 27 章)、阴影是两层的(第 25 章)、少用线(第 26 章)、先做灰度(第 28 章)。
有两处这本书没有跟它走,也照实写在了正文里:
- 它主张放弃模块化音阶、手挑一套字号。它的理由(音阶取整后会撞车)是对的,第 9 章那个 Demo 就把撞车算了出来。但这本书的处理是「音阶定初值 → 手工圆整 → 锁死」,而不是一开始就凭直觉挑——因为凭直觉挑正是那 18 个字号的来源。
- 它说「扔掉 hex,改用 HSL」。方向对,但那把尺子本身是歪的:
hsl(60 100% 50%)的黄和hsl(240 100% 50%)的蓝,白底对比度差 8 倍。2018 年 OKLCH 还没进 CSS,现在有了——见第 13 章。
目录
怎么读这本书
读第 1 章(立总账)、第 5 章(间距即语法)、第 14 章(对比度)、第 24 章(检查表)。这四章覆盖了「让界面立刻不难看」的绝大部分,而且全部可以当场检查。
就按顺序。前六卷是有依赖的:卷 I 给词汇,卷 II 到卷 V 一个维度一个维度地关自由度,卷 VI 把它们装进代码。每章末尾有一张「本章关掉的自由度」的账,主线 24 章加起来是 67 条——那就是第 24 章那张检查表的来源。
卷 VII 是补卷(第 25–28 章),讲主线刻意绕开的第三个维度:阴影、边框、图像,以及一个反直觉的工作法「先做灰度」。它不是主线的一部分,但如果你已经把前 24 章跑通了,那四章会让界面再往上抬一档。加上它,全书一共 78 条。
直接跳第 21 章,那里有一份可以粘进 MaterialTheme 的完整 token。但请至少回头看一眼第 13 章——否则你不会知道为什么不能用 HSL 调那套颜色。
这本书不教你培养审美。它教你把每一个数变得有出处——然后你会发现,「像样」是这件事的副产品。