对比度

把前景色与背景色的亮度差数值化的比率。WCAG 要求正文文本达到 4.5:1 以上以保证可读性。

对比度是把前景色 (文本或图标) 与背景色之间的相对亮度差用数值表示的比率。取值范围从 1:1 (没有差异) 到 21:1 (黑与白),是 Web 无障碍中保证文本可读性的重要指标。

W3C 的 WCAG (Web Content Accessibility Guidelines) 在 AA 级要求普通文本达到 4.5:1 以上、大号文本达到 3:1 以上 (成功准则 1.4.3)。AAA 级更严格,普通文本要 7:1 以上、大号文本要 4.5:1 以上 (同 1.4.6)。这里说的"大号文本"指 18pt 以上,粗体则为 14pt 以上。换算成 CSS 的 px,因为 1pt = 1/72 英寸、1px = 1/96 英寸,所以 18pt = 24px、14pt 约等于 18.7px。16px 的正文不算"大号文本",因此几乎所有正文都要按 4.5:1 一侧的标准来判定。这 4 个数值从 WCAG 2.0 到 2.2 都没有变化。

文本之外也有标准。成功准则 1.4.11 要求操作所必需的 UI 部件的边界与状态显示、以及理解内容所必需的图形,与相邻颜色的比达到 3:1 以上。表单边框、焦点环、图标、图表的系列色等都属于对象,只把正文颜色调好而漏掉 UI 部件是常见的疏漏。

日本的 JIS X 8341-3:2016 是与 WCAG 2.0 内容一致的标准,对比度成功准则的数值也相同。面向公共机构的运用指南要求满足 AA 级,但 JIS 本身属于自愿性标准,法律并没有直接规定必须符合 JIS。不要断言"JIS 规定为义务",实务上的判断依据是确认采购规格书或本公司的无障碍方针里承诺了什么。

计算对比度要用到颜色的相对亮度 (relative luminance)。公式是 (L1 + 0.05) / (L2 + 0.05),L1 是较亮一方、L2 是较暗一方的相对亮度。相对亮度是从 RGB 值出发、把 sRGB 的伽马校正也计算在内得出的,与单纯的 RGB 值之差并不相同。因此看上去"中间程度的灰"在数值上会偏向相当暗的一侧。以白色背景 (#ffffff) 为基准的实测值是:#333333 为 12.63:1、#595959 为 7.00:1、#767676 为 4.54:1、#999999 为 2.85:1。也就是说 #767676 几乎正好卡在 AA 的边界上,而 #999999 不能用于正文。这些都可以用 Chrome DevTools、axe、Lighthouse 等工具逐个确认。

做深色模式适配时,浅色模式和深色模式两边都要确认对比度。同一种灰色,背景一换比值就会大幅变动。#aaaaaa 在黑色背景 (#000000) 上是 9.04:1,满足 AAA,但在白色背景上只有 2.32:1,连 AA 都达不到。反过来,在浅色模式下很安全的深灰在深色模式下会沉入背景 (#333333 与 #1a1a1a 的组合是 1.38:1)。用 CSS 自定义属性分别管理两种模式的颜色,再各自验证,是稳妥的做法。如果使用了半透明的文字颜色 (rgba 或 opacity),就必须用与背景合成之后的实际颜色来计算,否则与实际情况不符。压在图片或渐变上的文字,要按条件最差的部分来判定。

一个常见的误解是对比度越高越好。也有用户反映纯黑配纯白 (21:1) 会让文字看起来发晕 (光晕现象),所以正文使用略微降低亮度的灰色,这种设计并不罕见。不过这属于设计上的选择而非标准的要求,降得过头就会跌破标准。与其瞄着上限去调,不如按"先确保稳稳超过 AA,再在这个范围内挑选阅读手感"的顺序来考虑,这样更安全。

与字符计数的关联在于,对比度低的文本难以阅读,会成为用户无法准确辨认字符的原因。字号小、字重细的时候,确保足够的对比度就更加重要。字符计数工具的 UI 设计上,照顾好输入文本与背景的对比度,也能提升用户的作业效率。

分享这篇文章