卷 VII · 表面· CH 28· 灰度优先 深度 28/28

先做灰度,颜色最后加

最后一章不给新知识,给一个顺序。而这个顺序会把前面二十七章的规则,从「你知道」变成「你做得到」。

颜色会掩盖偷懒顺带做完色觉自查全书结束

一个反直觉的建议

《Refactoring UI》里有一条工作法,我把它放在全书最后,因为它能强制你执行前面所有的章节

先用灰度做完整个界面,最后才加颜色

理由很硬:颜色是最容易的手段,所以它会掩盖你在别处偷的懒。

标题不够突出?染个蓝色,好像行了。
两个状态分不开?一个红一个绿,好像行了。
按钮不够明显?填个饱和色,好像行了。

三个「好像行了」,实际上一个问题都没解决——你只是把层级问题换成了颜色噪音。而这正是第 4 章那个「花」的生产过程。

对比一下

按这个顺序玩一遍:

  1. 灰度 + 未修——问题全暴露:标题和副标题几乎一样重,两个状态标签分不开,主次按钮的差别只剩一个边框。
  2. 上色 + 未修——「好多了」。但你只是用颜色盖住了问题,转回灰度它原样还在。
  3. 灰度 + 修过——一个颜色都没加,层级就出来了。标题放大加粗、分组之间拉开间距,全是卷 II 和卷 III 的手段。
  4. 上色 + 修过——这才对。颜色是锦上添花,不是救命。
灰度阶段该解决什么,上色阶段该解决什么
灰度阶段层级、分组、对齐、行长、留白、状态齐不齐
上色阶段语义:能点的 / 出错的 / 成功的 / 品牌的

换句话说:颜色只负责表达「是什么」,不负责表达「有多重要」。

「有多重要」由大小、间距、字重、位置负责——它们在灰度下依然有效。

它顺带解决了两件事

① 色觉自查。第 16 章那个「把界面转成灰度看看还分不分得开」的检查,在这个流程里是免费的——因为你本来就是从灰度开始做的。灰度下能分开的东西,所有色觉类型的人都能分开。

② 暗色模式。如果你的层级完全建立在颜色上,做暗色模式时你要重新调一遍所有关系。如果层级建立在大小和间距上,暗色模式只需要换一套颜色角色(第 16 章)——布局一行不动。

Compose 里实施起来很轻,一个 Preview 参数就够:

// 在开发期给自己一个「抽色」开关
@Composable
fun GrayscaleMode(enabled: Boolean, content: @Composable () -> Unit) {
    if (!enabled) { content(); return }
    val matrix = ColorMatrix().apply { setToSaturation(0f) }
    Box(
        Modifier.graphicsLayer {
            renderEffect = RenderEffect
                .createColorFilterEffect(ColorMatrixColorFilter(matrix.values))
                .asComposeRenderEffect()
        }
    ) { content() }
}

// 每个 Preview 配一对 —— 灰度那个是你真正该看的
@Preview(name = "1 灰度") @Composable
private fun PreviewGray() = AppTheme { GrayscaleMode(true) { OrderScreen(sample) } }

@Preview(name = "2 上色") @Composable
private fun PreviewColor() = AppTheme { GrayscaleMode(false) { OrderScreen(sample) } }

更土的做法一样有效:截图,用任何工具去饱和度。不需要写一行代码。

卷 VII 收尾

补卷四章,关掉了 11 个自由度:

第 25 章光从上面来;高度取六档;阴影是两层
第 26 章间距 → 底色 → 阴影 → 边框,用第一个成立的
第 27 章图有固有尺寸;压字必须加保底;容器定尺寸
第 28 章先灰度后颜色

加上主线的 67 条,全书一共 78 个你以后不用再临场决定的问题。

最后

这本书从第一句话开始就是同一件事:

你不缺审美,你缺的是出处

「难看」不是一种感受,是一个可以数出来的量——你这一屏上有多少个当时随手定的数。

设计师不是每次都选得比你好,是他们不每次都选

而你有一样他们没有的东西:你能把规则写成代码。他们靠眼睛和纪律维持一致,你可以靠 lint、类型系统和 CI。纪律会随时间衰减,CI 不会。

最后再邀请你做一次那件事:M 键。

这一页会浮出红线,把它自己的每一个间距、字号、行高、对比度都量给你看——数字是当场从 DOM 读的,不是写死的。

如果你现在能看着那些红线,说出「这里的间距是 s-6」「这段正文的对比度是 9.44:1,过 AAA」「这两个区块之间落在 8 的格子上」——

那这本书的事就办完了。

本章关掉的自由度本章 2 条 · 累计 78 / 78
  • 「什么时候加颜色」——最后。先用灰度把层级、分组、对齐、状态全做完,颜色只负责表达语义。
  • 「怎么确认层级不是靠颜色撑的」——抽掉饱和度再看一遍。这一步顺带做完了色觉自查和暗色模式的准备。