color-contrast() 仅 chrome 111+ 支持,firefox/safari 完全不识别;需用 lab()/lch() 输入以确保计算准确,且函数仅返回对比度值,不自动判断 wcag 合规性或 fallback。

color-contrast() 函数在 Chrome 111+ 才可用,旧版浏览器直接忽略
Chrome 111 是 color-contrast() 首个稳定支持版本,Firefox 和 Safari 当前(2024 年中)完全不识别该函数。它不是降级 fallback 的选项,而是“有就用,没有就失效”——CSS 解析器遇到不认识的函数会丢弃整条声明,不会保留默认值。
- 写成
color: color-contrast(white vs black, gray, #333);在 Safari 中,color属性直接不生效,元素沿用继承色或初始值 - 不能靠
@supports (color: color-contrast(...))安全包裹,因为语法校验阶段就报错(部分旧引擎甚至 crash) - 真要兼容,得用 JS 检测 + 动态设置,或彻底放弃该函数,改用预设对比度表 +
lab()/lch()手动计算
对比度计算依赖 LAB 色彩空间,sRGB 值直接传入会出错
color-contrast() 内部按 CIE LAB 计算相对亮度差,但函数参数必须是已解析为 LAB 的颜色值。你传 rgb(255, 0, 0) 或 #ff0000 进去,浏览器会先转成 sRGB,再转 LAB;而如果传 lab(54.2 80.8 -49.2),就跳过转换,直接参与计算——两者结果可能差 0.3+ 对比度单位。
- 推荐统一用
lab()或lch()输入,例如color-contrast(lab(99 0 0) vs lab(10 0 0), lab(50 0 0)) - 避免混用:不要写
color-contrast(#fff vs rgb(0,0,0), hsl(0 0% 50%)),不同色彩模型转换路径不一致,结果不可复现 - 工具链注意:PostCSS 插件如
postcss-color-function不处理color-contrast(),需手动确保输入已是 LAB
对比度阈值不是固定 4.5,AA/AAA 是 WCAG 标准,函数本身不判断合规性
color-contrast() 只返回一个数值(比如 4.72),它不关心这是 AA 还是 AAA,也不自动 fallback。你得自己写逻辑判断是否达标,再决定用哪个候选色。
- AA 小字号文本要求 ≥ 4.5,大字号(≥ 24px 或粗体 ≥ 19px)只需 ≥ 3.0;AAA 要求 ≥ 7.0(小字号)或 ≥ 4.5(大字号)
- 别指望
color-contrast(white vs black, gray, #333) >= 4.5这种写法——CSS 不支持表达式比较,必须靠 JS 或构建时生成 - 常见误用:把多个候选色塞进函数,以为它会“选最高分”,其实它只返回第一个满足阈值的色(按参数顺序),没达标就回退到列表末尾色
真实项目里,更可靠的是用 calc() + lch() 手动控制亮度差
想稳控对比度又不想绑死 JS,目前最可行的是绕过 color-contrast(),用 lch() 的明度通道(L)做差值估算。LAB/LCH 中 L ∈ [0,100],两色 L 差 ≥ 40 时,绝大多数组合能达到 AA 级别(实测误差率
立即学习“前端免费学习笔记(深入)”;
- 示例:
color: lch(calc(100 - var(--bg-l, 30)) 20 270);—— 背景 L 存在 CSS 变量里,文字 L 反向推算 - 注意:L 差只是强相关,不是等价。深红(L=30)配浅灰(L=75)差 45,但因色相差异,实际对比度可能仅 3.8
- 关键点:必须用
lch()而非lab(),因为 LCH 的 L 通道和人眼感知亮度更一致,LAB 的 L 是线性映射,容易高估暗色对比
事情说清了就结束。真正卡住人的从来不是函数怎么写,而是 LAB 空间里“看起来够亮”和“机器算出来够对比”之间那点微妙偏差。










