对比度 · 中文排版

汉字比拉丁字母
更需要对比度

可读性的研究、规范、经验值,几乎都是拿拉丁字母做出来的。 直接套到汉字上并不成立。同样的字号、同样的对比度,中文先糊。 这篇拆开讲三个原因,以及该往上提多少。

先自己看。下面这块,中文和英文用的是同一个颜色、同一个字号, 拖滑杆把对比度往下压,看哪一边先撑不住。「眯眼」那个按钮加一点模糊, 粗略模拟低分辨率屏幕和裸眼近视的情况。

同样的对比度,谁先糊

Lc 75
12px 这一行是十二像素的中文正文,笔画挤在一起。 Twelve pixel Latin body text here.
14px 这一行是十四像素的中文正文,笔画挤在一起。 Fourteen pixel Latin body text here.
16px 这一行是十六像素的中文正文,笔画挤在一起。 Sixteen pixel Latin body text here.

当前色值 ,白底上 WCAG )。 背景固定用白色,是为了让变量只剩对比度这一个。

往下压到 Lc 75,也就是 APCA 认可的"正文可用"档,英文那几行还清楚, 中文 12px 那行已经开始发灰发糊了。这不是错觉,有三个叠加的原因。

一、同样的框,塞的笔画差一个数量级

拉丁小写字母的骨架极简:o 一个圈,a e c 一两笔, 最复杂的 m 也不过三根竖加两个肩。汉字呢:

o1 m3 8 9 9 16 19
右下角是笔画数。这些都是正文里天天出现的常用字,不是生僻字。

笔画多了,笔画之间的空白(字腔)就必然变窄。 而人眼分辨文字靠的不是笔画本身,是笔画之间的空白。 「日」和「目」的区别就是中间多一道横;「未」和「末」的区别是哪一横更长。 这些区别全落在几个像素宽的缝隙上。

用信号的说法:汉字的空间频率高得多。对比度下降的时候, 高频成分永远先丢:大轮廓还在,细节先没。 于是中文糊掉的表现不是"看不见",是"认不出是哪个字", 得靠上下文猜,读起来就累。

有一点是汉字占便宜的,得说清楚

汉字几乎撑满整个字框,而拉丁小写的主体高度(x-height)通常只有字号的一半上下。 所以同样 16px,中文看上去更大。 这一点确实是有利的,也是很多人觉得"中文不用调"的直觉来源。

但这两件事的作用方向不一样:字面大,帮的是"看得见"; 字腔小,害的是"认得出"。正文阅读拼的是后者。

二、中文字体的 Regular,实际比拉丁的 Regular 更细

这是个被结构逼出来的结果。要在同一个字框里塞下十几笔而不糊成一团, 单笔就必须做细。所以中文字体的常规字重,笔画的绝对粗细往往达不到 同字号拉丁常规字重的水平。尤其是竖笔以外的横笔,为了留出行气还会更细。

这一点在黑体/无衬线里最明显。宋体靠横细竖粗、 靠衬线(字脚)把节奏撑住,屏幕上小字反而更容易散架; 而黑体笔画粗细均匀,一旦整体做细,就是整片一起变淡。

三、抗锯齿和光渗,专门吃细笔画

屏幕渲染时,一根不足整像素宽的笔画会被抗锯齿摊成几个灰点。 笔画越细,"真正达到目标颜色的像素"占比越低, 实际落到眼睛里的对比度低于你设置的那个值。 汉字满篇都是这种细笔画,损失是成片发生的。

深色模式还要再加一层。浅色的字压在深色底上会发生光渗 (亮区往暗处溢出),笔画显得更胖, 对拉丁字母来说这顶多是"看着粗一点", 对本来缝隙就只有一两像素的汉字来说,是缝隙被直接填死。 「四」变成一个黑块,「臘」糊成一团。

三件事叠加:笔画更密、单笔更细、渲染损失更大。所以同样的数字,中文的实际观感要打折。

那该提多少

APCA 本身其实已经给出了思路。它的用法不是"看 Lc 过没过线", 而是拿字号和字重去查一张表:同样的 Lc, 字越小、笔画越细,要求就越高。

汉字正文在这张表上的位置,相当于比同字号的拉丁正文再细一档。 顺着这个逻辑外推,我在配色工作台里 给中文正文用的是这条线:

用途拉丁中文
正文Lc 75Lc 90
次要文字Lc 60Lc 75

几条更具体的:

  • 中文正文别低于 16px。14px 在高分屏上勉强,在 1080p 的外接显示器上就开始费劲了,而后者仍然是国内办公场景的大多数。
  • 深色模式下别给中文用 Light / 300 字重。光渗加细笔画,是最糟的组合。深色那套的中文正文,字重宁可比浅色那套重一档。
  • 弱化文字别只靠调淡。拉丁排版里把颜色调淡来区分层次很常见,中文这么干掉得快。改用字号、间距、位置来分层,颜色只降一点点。
  • 中英混排时,瓶颈永远是中文那部分。按中文的线来定,英文自然富余。

这篇的边界在哪

上面那张「中文该用多少 Lc」的表是外推,不是标准。 APCA 目前没有公开的 CJK 字重查找表,WCAG 2.1 也完全没有区分书写系统。 我是按 APCA 自己"笔画越细要求越高"的逻辑,把汉字正文当作比同字号拉丁再细一档来推的。 工作台里这一档也明确标成建议,不当作硬性要求,就是这个原因。

另外,中文屏幕可读性的实证研究比拉丁那边少得多, 而且多集中在阅读速度和字号,不是对比度。 如果你手上有更硬的数据,我很想看到,这一档随时可以按证据调整。

动手

配色工作台 的预览区里,正文那一段特意中英各摆了一行,就是为了让这个差别当场看得见; 双查表里中文那一档也是单独判的。 文章里所有数字和这块演示,用的都是同一套引擎。

接着看

为什么 WCAG 的对比度公式在深色模式下不准 同样 4.5:1,深字压白底 Lc 71,浅字压黑底只有 Lc 29。公式是对称的,人眼不是。 配色工作台 浅深双查、双口径、中文单独判档,导出成对的 CSS 变量。