专栏名称: 前端早读课
我们关注前端,产品体验设计,更关注前端同行的成长。 每天清晨五点早读,四万+同行相伴成长。
目录
相关文章推荐
51好读  ›  专栏  ›  前端早读课

【第3513期】如何在 CSS 中让浏览器选择对比色

前端早读课  · 公众号  · 前端  · 2025-05-21 08:00

正文

请到「今天看啥」查看全文


contrast-color() 并不意味着它自动生成的颜色组合就是可访问的。我们仍然有可能选择了一种背景色,它无论配黑色文字还是白色文字,都无法达到足够的对比度。最终是否符合无障碍标准,还是需要人来判断 —— 设计师、开发者、测试人员等都要参与确保对比度足够。

事实上,如果你现在(2025 年 5 月)在 Safari Technology Preview 中试用这个功能的演示,你会发现,当背景色是中间色调时,系统选择的文字颜色常常对比度不够,读起来很费劲。比如这个蓝色 #317CFF ,系统选择的对比色是黑色。

一个中等偏深蓝色的按钮,文字是黑色的。文字几乎看不清。

而如果用白色文字,视觉上的对比明显更好:

同样的蓝色按钮,这次用白色文字。清晰易读,效果好很多。

那到底发生了什么?为什么浏览器会选了一个对比度较差的颜色?

目前 Safari Technology Preview 的实现,使用的是 WCAG 2(Web 内容无障碍指南第二版)中官方定义的对比度算法。如果你用 WebAIM 提供的专业对比度检测工具去测试这个蓝色背景,系统确实推荐使用黑色文字而不是白色。WCAG 2 是当前 web 无障碍标准中最权威的一套规范,很多国家和地区甚至将其列入法律要求。

按照 WCAG 2 的算法计算,黑色文字与 #317CFF 的对比度为 5.45:1,而白色文字的对比度为 3.84:1。 contrast-color() 函数只是简单地选择对比度数值更大的那个颜色 —— 而 5.45 显然比 3.84 要高。

附图:WCAG 2 对比度检测工具结果截图,显示白底蓝字和黑底蓝字的对比度结果。黑色通过检测,白色不通过。但从视觉上来看,白色反而更清晰。

在 WebAIM 的检测工具中测试黑白文字在中等深蓝背景下的对比度。

当计算机执行 WCAG 2 算法时,黑色文字确实在数学上对比度更高;但从人的视觉感受来说,黑色文字反而更难读。这种 “数字对比高但人眼感受差” 的情况其实并不少见,也正是 WCAG 2 的对比算法长期以来饱受争议的原因之一。

实际上,推动无障碍标准更新到 WCAG 3 的一个重要原因,就是希望改进这个对比算法。

可感知对比度算法(APCA, Accessible Perceptual Contrast Algorithm)就是 WCAG 3 考虑纳入的新算法之一。你现在就可以通过网站 apcacontrast.com 来试用 APCA 对比度计算器。下面我们就来看看这个新算法如何评估黑白文字在这款蓝色背景下的对比情况。

在 APCA 对比度计算器中测试黑白文字在中等偏深蓝色背景下的对比度

这个对比算法将黑色文字在蓝色背景上的得分评为 Lc 38.7,而白色文字得分为 Lc -70.9。判断哪种对比更强时,暂时忽略负号,直接比较数值大小:70.9 明显大于 38.7。所以 APCA 测试结果显示白色文字的对比度明显更高 —— 而这也更符合人眼的直观感受。

(在 APCA 的计分系统中,负数仅仅表示文本比背景颜色浅。浅色模式 = 正数,深色模式 = 负数。)

那么为什么 APCA 的结果比 WCAG 2 更合理?

因为 APCA 的算法是基于人眼感知来计算对比度,而不是单纯用数学公式。这考虑到了人类对色相和亮度的感知并不是线性的。如果你对 LCH 和 HSL 这两种颜色模型有所了解,应该听说过新一代的颜色计算方法更接近人眼的视觉逻辑,更能判断哪些颜色亮度 “看起来” 相近。“Lc” 就是 “亮度对比度”(Lightness Contrast)的缩写,比如 “Lc 75”。

幸运的是, contrast-color() 背后的算法是可以更换的。这个功能最早在 2021 年 3 月的 Safari Technology Preview 122 中推出(当时这个函数还叫 color-contrast )。当时还没决定采用哪个更好的算法。

CSS 标准目前仍要求浏览器使用旧的 WCAG 2.1 算法,但也留有升级的空间,标准中写道:

“目前仅支持 WCAG 2.1,但这个算法已知存在问题,特别是在深色背景下。未来版本可能会引入其他对比算法。”

而 WCAG 3 中应使用哪种算法的讨论仍在进行中,包括关于新算法的授权许可问题。

与此同时,团队在配色时仍应格外关注无障碍问题。

如果你选择的是明显偏亮或偏暗的颜色,哪怕背后算法是 WCAG 2, contrast-color() 的表现也会很好。但在处理中间亮度的颜色时,各种算法的结果可能差异很大。

此外,即使未来使用了更先进的算法, contrast-color() 这个函数也不能完全保证颜色组合就是无障碍的。

“这个颜色对比度更强” ≠ “这个颜色对比度足够”。有很多颜色,不管是配黑色还是白色,在小字号或细字体时,都无法达到足够的对比度。

【第3496期】2025 年提升性能的最佳 CSS 单行代码:contain-intrinsic-size

现实中的对比度设计

在思考色彩对比度时,我们还可以借助另一个有用的工具: prefers-contrast 媒体查询,可以让我们为希望更高对比度的用户提供替代样式。

@media (prefers-contrast: more){
 /* 提供更高对比度的样式 */
}

让我们来设想一个真实的设计场景:我们正在为一家树苗园艺网站设计页面,他们的品牌主色是鲜亮的中度绿色 #2DAD4E ,设计团队非常希望将这个颜色用作按钮的背景色。

为了方便起见,我们假设 CSS 已经使用 APCA 替代了 WCAG 2 算法。那么 contrast-color() 返回的文字颜色将是白色,而不是黑色。

但我们查了一下这个颜色组合,会发现对于某些用户,尤其是在字体较小时,对比度可能不够。这时候就需要好的设计来弥补。







请到「今天看啥」查看全文