什么是颜色对比度,为什么它关乎可读性

颜色对比度(Color Contrast Ratio)衡量前景色与背景色之间的相对亮度差。它不是"两种颜色看起来的差别大不大"这种主观感受,而是一个有明确定义、可重复计算的比值,范围从 1:1(完全相同)到 21:1(纯黑配纯白)。对比度之所以重要,是因为文字能不能被轻松读出来,根本上取决于笔画与底色之间的亮度差,而不是色相差别。两个敏感度不同的人、两台亮度不同的屏幕,对"好不好看"的判断会差很多,但对"亮不亮得清"的判断,用同一个公式就能算出来。

在 Web 无障碍领域,这套判断标准由 W3C 的 WCAG(Web Content Accessibility Guidelines,Web 内容无障碍指南)给出。WCAG 把"文字与背景要有足够对比"列为一项硬性成功标准(1.4.3 对比度(最低)与 1.4.6 对比度(增强)),目的不是审美,而是让弱视、老花、色觉差异,以及在强光下或低分辨率屏幕上使用设备的人,也能稳定地读取内容。对一个面向公众的网站来说,达到 AA 级别通常被视为最低可接受的门槛;达不到,就意味着一部分用户被实实在在地挡在内容之外。这也解释了为什么很多设计系统在交付前会专门跑一轮对比度校验。

相对亮度:对比度的计算基础

对比度的计算分两步,核心概念是"相对亮度"(Relative Luminance)——它表示某个颜色在经历过人眼感知加权之后,看起来有多亮。注意这里的"亮度"不是屏幕上 raw 的 0–255 数值,而是先对 sRGB 做了 gamma 校正(把非线性的编码值还原成接近真实光强的值)之后得到的。

对每一个颜色通道,先把 0–255 归一化到 0–1,记为 c;如果 c ≤ 0.03928,线性值取 c ÷ 12.92,否则取 ((c + 0.055) ÷ 1.055) 的 2.4 次方。得到线性 R、G、B 之后,再按人眼敏感度加权求和:

相对亮度公式:L = 0.2126 · R + 0.7152 · G + 0.0722 · B

三个权重加起来正好等于 1。绿色权重 0.7152 最大,是因为人眼对绿色最敏感;蓝色权重 0.0722 最小,是因为同样的光强下蓝色看起来最暗。这也说明一个常见误区:对比度只跟"亮不亮"有关,跟"红还是蓝"无关——把红色调深或调浅,对对比度的改变,永远小于同等幅度改变它带来的亮度变化。

拿到两个颜色的相对亮度 L1(较亮)和 L2(较暗)后,对比度按下式计算:

对比度公式:(L1 + 0.05) ÷ (L2 + 0.05)

分母中的 +0.05 来自人眼在完全黑背景下的"阈值亮度"(黑也不是绝对零亮),它让最暗的情形不会得到无穷大或除零的结果。计算时务必把较亮的颜色放在分子,较暗的放在分母,否则会得到小于 1 的倒数。

WCAG 2.1 的对比度门槛

下面这张表是 WCAG 2.1 对不同类型内容的最低要求。它把"正文"和"大文本/UI 组件"分开对待,因为二者对对比度的需求不同(原因见后文"对比度与字号的关系")。

内容类型AA(最低)AAA(增强)说明
普通正文文本≥ 4.5:1≥ 7:1适用于绝大多数网站正文,AA 是行业公认底线
大号文本(≥18pt,或 ≥14pt 且加粗)≥ 3:1≥ 4.5:1字号够大时放宽门槛
UI 组件与图形对象(按钮边框、图标、输入框轮廓、图表线条)≥ 3:1—WCAG 2.1 对 AAA 的 UI 组件未单列更高要求,但图形对象建议 ≥ 4.5:1

怎么用:先判断你校验的对象是"正文"还是"大文本/UI 组件"。若是正文,目标至少要 4.5:1(追求更高可读性冲 7:1);若是按钮文字、图标、链接下划线这类非正文元素,达到 3:1 即满足 AA。很多团队会把自己内部规范定得比 WCAG 更严,例如正文统一要求 7:1,这属于更稳妥的增强做法。

常见配色的实际对比度

光看数值可能没概念,下面把几组设计师常踩的配色算出来。注意最后两组:#767676 与 #777 只差一个色值档位,结果一个勉强通过 AA、一个刚好不达标。

前景色背景色相对亮度 L(前景)对比度判定
#000000(黑)#FFFFFF(白)0.000021:1远超 AAA,最安全
#333333(深灰)#FFFFFF0.0331≈ 12.6:1达 AAA,常规正文首选
#595959(中灰)#FFFFFF0.1000≈ 7:1正好达到 AAA 正文门槛
#767676(浅灰)#FFFFFF0.1810≈ 4.54:1刚好越过 AA 4.5:1(临界)
#777777(浅灰)#FFFFFF0.1844≈ 4.48:1差一口气,未达 AA
#949494(更浅灰)#FFFFFF0.2960≈ 3.03:1仅满足大文本/UI 组件 AA

怎么用:这张表最该记住的是 #767676 与 #777 这对"邻居"。很多设计系统把正文默认灰设成 #767676,它卡在 4.54:1,刚好压线通过;一旦有人"随手调浅一档"改成 #777,立刻跌到 4.48:1,AA 不达标,而肉眼几乎看不出区别。所以正文灰不要凭感觉取,要按公式卡 4.5:1。若你正在用取色工具挑色,可配合 图片取色器 把屏幕上的颜色读成十六进制,再回来校验。

公式与真实算例

下面用真实数字走一遍,验证工具算得对不对。

算例 1(白底黑字 = 21:1):黑色 L = 0,白色 L = 1。对比度 = (1 + 0.05) ÷ (0 + 0.05) = 1.05 ÷ 0.05 = 21:1。这是所有配色的理论上限,也是对比度比例尺的顶端。

算例 2(#595959 灰字配白底 ≈ 7:1,达 AAA):#59 = 89,归一化 c = 89 ÷ 255 ≈ 0.3490;因 c > 0.03928,线性值 = ((0.3490 + 0.055) ÷ 1.055)^2.4 ≈ (0.3829)^2.4 ≈ 0.1000。三个通道相同,L = 0.2126×0.1 + 0.7152×0.1 + 0.0722×0.1 = 0.1000。对比度 = (1 + 0.05) ÷ (0.1 + 0.05) = 1.05 ÷ 0.15 = 7:1,正好命中 AAA 正文的 7:1 门槛。

算例 3(为什么 3:1 只够大文本):取 #949494 配白底,L ≈ 0.2960,对比度 = 1.05 ÷ (0.2960 + 0.05) ≈ 1.05 ÷ 0.346 ≈ 3.03:1。这个值只够"大文本或 UI 组件"的 AA,拿去做小正文会糊。原因在下一节。你可以顺手用 百分比计算器 验证 (L1+0.05)/(L2+0.05) 这类比值运算。

如何使用本工具

  1. 点击色块或直接输入十六进制色值,分别设置前景色(文字)与背景色
  2. 工具实时计算对比度并显示 AA/AAA 各级别判定结果
  3. 预览区以所选配色渲染示例文字,直观查看效果
  4. 未通过时调整颜色,直到满足目标级别

常见问题(color-contrast 专属)

相对亮度(Relative Luminance)是什么,它和纯色值有什么不同?相对亮度是经过人眼感知加权、并做过 gamma 校正之后得到的"看起来有多亮"的数值,范围 0(黑)到 1(白)。它和屏幕上 0–255 的 raw 色值不是一回事:sRGB 编码是非线性的,所以必须先用 (c+0.055)/1.055 的 2.4 次方把通道"线性化",再按 0.2126/0.7152/0.0722 加权求和。对比度公式只用这个相对亮度,不关心色相,因此"深红"和"深蓝"只要亮度一样,对比度就一样。

正文该用 3:1 还是 4.5:1,二者怎么选?看对象。普通正文(小字)必须 ≥ 4.5:1(AA),追求更高可读性可冲 7:1(AAA)。只有"大号文本"(≥18pt,或 ≥14pt 且加粗)和"UI 组件/图形对象"(按钮边框、图标、输入框轮廓)才允许放宽到 3:1。简单记:凡是用户要"读"的小字,用 4.5:1;凡是用户要"认出形状/边界"的非文字元素,用 3:1。

对比度要求与字号有什么关系?关系很直接:字号越大、笔画越粗,人眼在较低亮度差下也能分辨形状,所以 WCAG 对大文本只要求 3:1;正文小字笔画细,亮度差不够时笔画会糊在一起,因此要求 4.5:1。也就是说,同一组配色,做大标题可能达标,做正文却会不达标——绝对不能因为"大标题看着清楚"就默认它也能做小字正文。

为什么浅灰文字(如 #777)常常不达标?因为浅灰离白色的亮度差太小。从上文算例可见,#767676 配白底约 4.54:1 才勉强过 AA,而只深一档的 #777 就跌到 4.48:1 不达标。设计师常把浅灰当"柔和高级",但柔和恰恰来自亮度差小,而这正是可读性的敌人。需要做浅色文字时,务必下压到 #595959 附近(≈7:1)才稳妥。

工具给出的对比度比值应该怎么解读?比值越大越清晰,1:1 表示前景背景无差别、完全不可读,21:1 是顶配。看结果时重点对照三档门槛:≥7:1 可标 AAA 正文;≥4.5:1 可标 AA 正文;≥3:1 只够大文本与 UI 组件。若未达目标级别,工具会给出未通过提示,此时加深文字或提亮背景即可。文案长度核对可配合 字数统计器 一起用。