Skip to content
返回博客
教程

WCAG 颜色对比度完全指南:AA、AAA 与 APCA 算法详解

WCAG 颜色对比度完全指南:从 4.5:1 AA 到 7:1 AAA 阈值、APCA Lc 算法、色盲适配,到如何修复无法通过的颜色组合,一篇讲透。

15 分钟阅读

WCAG 颜色对比度:AA、AAA 与 APCA 算法

你上线了一个按钮,品牌橙底配白字,在 4K 显示器上看起来锐利干净。然后无障碍审计报告飘红:WCAG 对比度只有 1.97:1,远低于正文 4.5:1 的 AA 阈值。这颗你眼里没毛病的按钮,对全球约 2.2 亿低视力用户而言根本读不清。本文逐一拆解修这个坑需要的所有数字:WCAG 2 的比率、AAA 等级、新出的 APCA Lc 算法、八类色觉差异,以及一份可以直接塞进构建脚本的 JavaScript 实现。

速查表:WCAG 与 APCA 阈值一览

标准正文文本大号文本UI 元素 / 图标备注
WCAG AA≥ 4.5:1≥ 3:1≥ 3:1法律底线
WCAG AAA≥ 7:1≥ 4.5:1≥ 3:1增强目标
APCA bodyLc 75+Lc 60+Lc 45+(图标)草案,感知导向

「大号文本」指 ≥ 18pt 常规字重或 ≥ 14pt 粗体(约对应 CSS 中的 24px 和 18.66px)。「UI 元素」涵盖表单边框、焦点环,以及任何用户必须辨识才能操作页面的图形对象。Logo 和纯装饰图形不受对比度要求约束。

WCAG 颜色对比度是什么?

WCAG 对比度是一个从 1:1(无对比)到 21:1(最大对比)的数值,用来比较文字与其背景之间的相对亮度(relative luminance)。Web 内容可访问性指南要求正文文本至少达到 4.5:1(AA),或在增强合规场景达到 7:1(AAA)。

这个数字单独撑起了全球绝大多数的无障碍审计。W3C 早在 2008 年的 WCAG 2.0 中发布了它,在 2.1(2018)与 2.2(2023)中持续打磨,如今所有主流监管机构都把它作为参考:美国的 ADA、自 2025 年 6 月起强制执行的欧盟无障碍法案(EAA)、联邦机构遵循的 Section 508、加拿大的 AODA,都把 WCAG 2.x AA 视为事实上的底线。

抛开法律层面,对比度还有现实理由。全球约 2.2 亿低视力(low vision)用户并非失明,他们能看屏幕,但前提是文字与背景之间的对比足够强。约 8% 的男性和 0.5% 的女性存在色觉异常。年长读者的晶状体会发黄、瞳孔口径变小,60 岁以后感知到的对比度功能性地下降 20%–30%。户外用手机时,眩光又会再扣掉 20%–40%。一个在你桌面上达到 4.5:1 的页面,正是这些用户仍能读得动的最低门槛。

最该关心对比度的有这几类人:上线生产 UI 的前端工程师、挑选品牌色板的设计师、跑审计的无障碍专家,以及为法律风险负责的合规团队。数学不复杂,背后的取舍才麻烦。

WCAG 2.x 对比度:公式与阈值

W3C 把对比度定义为三个简短步骤。计算 WCAG 对比度的流程是:(1)把每个颜色从 gamma 编码的 sRGB 转换为线性光值,(2)使用对应人眼对红绿蓝感光强度的固定系数算出相对亮度,(3)将两个亮度做带常数偏移的相除,以处理接近纯黑的情况。

WCAG 2.1 §1.4.3 中的相对亮度公式如下:

L = 0.2126 × R_lin + 0.7152 × G_lin + 0.0722 × B_lin

R_linG_linB_lin 是经 sRGB gamma 曲线反解后得到的线性光通道值。0.7152 的绿色权重反映人眼对绿光的强烈敏感,按单位光能量计,绿色的「视觉响度」大约是蓝色的 7 倍。

对比度公式是:

ratio = (L_lighter + 0.05) / (L_darker + 0.05)

加 0.05 是为了防止纯黑(L = 0)时出现除零,并且把纯白对纯黑的最大值精确定在 (1 + 0.05) / (0 + 0.05) = 21:1。最小值是 1:1,即两色完全相同。

下面是 30 行左右的原生 JavaScript 完整实现,零依赖,哪里都能跑:

// sRGB hex → 线性光通道
function srgbToLinear(channel8bit) {
  const v = channel8bit / 255;
  return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
}

// "#RRGGBB" → 相对亮度 [0, 1]
function relativeLuminance(hex) {
  const h = hex.replace("#", "");
  const r = parseInt(h.slice(0, 2), 16);
  const g = parseInt(h.slice(2, 4), 16);
  const b = parseInt(h.slice(4, 6), 16);
  return (
    0.2126 * srgbToLinear(r) +
    0.7152 * srgbToLinear(g) +
    0.0722 * srgbToLinear(b)
  );
}

// 计算两个 hex 颜色之间的 WCAG 2.x 对比度
function contrastRatio(hexA, hexB) {
  const lA = relativeLuminance(hexA);
  const lB = relativeLuminance(hexB);
  const [lighter, darker] = lA > lB ? [lA, lB] : [lB, lA];
  return (lighter + 0.05) / (darker + 0.05);
}

// 示例:白底上的深石板灰正文
console.log(contrastRatio("#475569", "#ffffff").toFixed(2));
// → "7.58",超过 AA 4.5:1,刚好越过 AAA 7:1

把任意两个十六进制颜色粘进颜色转换器,你会得到一模一样的数字,旁边还会渲染 APCA Lc 值、色域分类,以及八个通道的 CVD(色觉异常)预览。阈值本身写得很清楚:

元素AA 下限AAA 下限备注
普通正文文本4.5:17:1< 18pt 常规字重 / < 14pt 粗体
大号文本3:14.5:1≥ 18pt 常规字重,或 ≥ 14pt 粗体
UI 组件 / 图标3:12018 年 WCAG 2.1 §1.4.11 新增
Logo 与装饰元素豁免豁免无对比度要求

CSS 单位换算最容易踩坑:浏览器默认下 18pt = 24px,14pt = 18.66px。现代默认的 16px 正文字号低于「大号文本」门槛,所以要走更严格的 4.5:1 AA 规则。一个 20px 且 font-weight: 700 的标题则属于大号文本,可以走更宽松的 3:1。

还有一个细节常被团队忽视:WCAG 中的「大号文本」豁免取决于实际渲染时的可读性,跟标题语义没半毛钱关系。一个 14px 的 <h2> 不是大号文本,仍需 4.5:1;而一段 24px 的营销正文段落才是大号文本,可以走 3:1 下限。规则只看渲染出来的像素尺寸和字重,不看标签名。审计工具会揪出不匹配的情况;权威依据是你的 CSS,而不是 HTML 语义。

公式里 +0.05 的常数有具体来由:它代表 flare 项,也就是屏幕表面反射的环境光,会把纯黑的表观亮度抬到一个最低底线。没有它,OLED 渲染纯黑对纯白会直接除零。有它之后,可达到的最大比率正好是 21:1,每个无障碍工具里你都会看到这个数字。一旦考虑 flare,物理屏幕就没办法做出超过 21:1 的对比度,这也是 WCAG 量表停在这里的原因。

AA vs AAA:你该瞄准哪一档?

AA 是法律底线,AAA 是进阶目标。绝大多数商业网站都把目标定在 AA,因为想通过 AAA,品牌色往往要被压向中性灰阶,这是市场团队普遍不会同意的事。这里的取舍不是「越高越好」,而是用户覆盖面与品牌表达之间的权衡。

场景推荐档位理由
通用商业网站AAADA / EAA 合规基线;法院引用的就是 WCAG 2 AA
政府 / 公共服务AAASection 508 与对应欧盟条款建议 AAA
医疗 / 教育AAA用户群体覆盖更多低视力比例
内部仪表盘AA受众明确,ROI 上可接受
营销落地页AA + 品牌豁免品牌色可用于 Hero / CTA,正文仍需 AA

AAA 的隐藏成本第一次出现,往往是你试图让品牌饱和橙色在白底上跨过 7:1 的瞬间,结论是根本做不到。你要么把橙色压暗到不再像你的品牌,要么接受 AA,把橙色搬到深色背景上,让它轻松达到 AAA。包括一些对无障碍要求很高的公司在内,许多团队都明确把正文目标定在 AA,仅在错误提示、法律声明这种关键文字上向 AAA 推进。

监管者没有等 AAA 普及。ADA 2024 年的网页无障碍法规直接引用 WCAG 2.1 AA;自 2025 年 6 月起强制执行的欧盟无障碍法案,要求所覆盖的数字服务必须达到 WCAG 2.1 AA;美国联邦政府的 Section 508 把 WCAG 2.0 AA 作为基线(在可行的情况下建议 AAA);加拿大、安大略省的 AODA 同样指向 WCAG 2.0 AA。规律一致:AA 是门槛,AAA 是追求。

APCA:新的感知导向算法

APCA(Advanced Perceptual Contrast Algorithm,由 Andrew Somers 在 Myndex 名下设计)是 WCAG 3 的候选算法之一。它把 WCAG 2 的对称比率替换为带极性符号的 Lc 分数,范围 -108 到 +108:符号告诉你对比方向(深字浅底,还是浅字深底),数值反映的是真实自发光显示器上的感知对比。

APCA 之所以重要,是因为 WCAG 2 的对称公式漏掉了两个现实效应:

  • 极性不对称(polarity asymmetry)。即使 WCAG 比率一样,浅字深底和深字浅底的阅读体验也不同。WCAG 2 对两种方向返回相同的数字,APCA 不会。
  • 显示器建模。WCAG 2 的公式源自纸质印刷的亮度模型,APCA 则是针对典型办公室光照下的 sRGB 显示器调校的,更接近用户实际看到的样子。

代价是 APCA 更复杂(涉及极性敏感的指数项和字重调整),并且还不是正式的法规标准。Adrian Roselli 2026 年 4 月的分析依然是关于 APCA 现状最清晰的总结:算法本身有依据,但 WCAG 3 还在 Silver 轨道的早期草案阶段,APCA 尚未被正式确立为官方算法。

APCA Bronze 级别的阈值(也是大多数团队实际在用的底线)如下:

用途推荐 Lc最低 Lc
正文文本(16px,字重 400)90+75
大号文本(24px,字重 400)75+60
UI 元素与非文本图标60+45
点缀文字 / 占位符30+30

APCA 真正值得关注的地方,也是颜色转换器同屏并列展示两套指标的原因,是它和 WCAG 2 出现分歧的那些场景:

  • #FFA500(橙)配 #FFFFFF:WCAG 2 给出 1.97:1,AA 明显不通过。APCA 同意,约 Lc 38,也不通过。两者都说不行,但我亲眼见过很多设计师照旧把它上线,理由是「看起来还行」。
  • #767676(中灰)配 #FFFFFF:WCAG 2 给出 4.54:1,刚刚越过 AA 4.5:1,技术上算通过。APCA 给出的分数约为 Lc 60,低于 APCA Bronze 正文 75 的阈值。WCAG 通过,APCA 不通过。用户的真实体感更接近 APCA 的判断:白底上的这种灰,在正文字号下比比率显示的更难读。
  • #3b82f6(Tailwind blue-500)配 #000000:WCAG 2 给出 5.71:1,AA 顺利通过。APCA 大约 Lc 65,低于正文 Lc 75 的下限。深底配亮蓝文字这种深色模式常见配色,是「WCAG 过,APCA 警告」的经典案例。

你不需要二选一。大多数生产团队最后的务实姿态是:把 WCAG 2 AA 作为合规基线(毕竟合规审计就是按它跑),同时并行跑一遍 APCA,作为「这个组合到底读不读得下来」的直觉检查,尤其是面对深色模式和饱和品牌色时。颜色转换器把两套数字放在同一行展示,省得你来回切换工具。

色觉异常与对比度之外

对比度只是颜色无障碍的一半。约 8% 的男性和 0.5% 的女性看到的颜色与教科书中的三色视者不同,其中最常见的 deuteranomaly(绿色弱)正好落在我们到处用来表示「成功 / 失败」的红绿配色之间。WCAG 1.4.1(Use of Color)明确禁止把颜色作为信息的唯一载体,这条规则正是为此而存在。

完整的色觉差异分类可以分为三组:dichromacy(缺一种视锥)、anomalous trichromacy(一种视锥偏移)和罕见的 monochromacy(全色盲)。

类型通俗叫法受影响通道人群占比(男 / 女)
Protanopia红色盲L 视锥缺失1.0% / 0.01%
Deuteranopia绿色盲M 视锥缺失1.1% / 0.01%
Tritanopia蓝色盲S 视锥缺失0.003% / 0.003%
Protanomaly红色弱L 视锥偏移1.3% / 0.02%
Deuteranomaly绿色弱M 视锥偏移5.0% / 0.4%
Tritanomaly蓝色弱S 视锥偏移0.01% / 0.01%
Achromatopsia全色盲三种视锥全部缺失0.003%(极罕见)
Cone monochromacy部分灰度视仅一种视锥0.001%

光是 Deuteranomaly 就占男性的 5%,每 20 人就有 1 人。他们眼里红色错误指示和绿色成功指示几乎是同一种橄榄褐。解决方案不是重做颜色系统,而是多加一条信息通道:红色错误图标搭配「×」形状和「Error」文字标签,能扛住表中所有变体;一个孤零零的红点扛不住。

代码层面模拟 CVD 用两套标准矩阵:Brettel–Viénot–Mollon(1997)用于 dichromacy,Machado–Oliveira–Fernandes(2009)用于 anomalous trichromacy。Brettel 的做法是把输入色投影到剩余两种视锥响应张成的平面;Machado 用严重程度对视锥偏移做参数化。两者都可以用 SVG filter 或 CSS 矩阵实现。颜色转换器把所有 8 种变体打包成一键预览,让你能在不离开页面的情况下扫一遍品牌色在不同色觉下的表现。

下面一段 SVG filter,放进页面后通过 ID 引用,就能在浏览器里做即兴的 Protanopia 模拟:

<svg style="display: none">
  <filter id="protanopia">
    <feColorMatrix type="matrix" values="
      0.567 0.433 0.000 0 0
      0.558 0.442 0.000 0 0
      0.000 0.242 0.758 0 0
      0.000 0.000 0.000 1 0"/>
  </filter>
</svg>

<style>
  .preview-protanopia { filter: url(#protanopia); }
</style>

.preview-protanopia 套在页面外层容器上,就能看到红色盲眼中的画面。换用 Deuteranopia 和 Tritanopia 的矩阵照搬即可(系数都写在 Brettel 论文里,主流 CVD 模拟库也都打包好了)。Chrome DevTools 的 Rendering 面板下的「Emulate vision deficiencies」内置了同样的模拟器,做快速检查很好用,做 CI 截图就力不从心了。

更深一层的规则,超越模拟本身:永远不要让颜色成为两个状态之间唯一的差异。图标在形状上要不同(× vs ),状态在文字标签上要不同(「Error」vs「Success」),分类在图样上要不同(实心 vs 斜线填充)。颜色是这些信号的乘数,不是替代品。

有一类失败对比度检查器抓不到,但 CVD 模拟器能抓出来:仅靠色相区分的饼图扇区、用颜色区分国家的地图图例、依赖红黄绿渐变的状态徽章。它们跟背景之间可能完美通过 WCAG 2 对比度,但放在一起被 Deuteranope 看的时候就完全分不清。规则是:要检查的是设计内部相邻颜色之间的可辨识度,而不只是颜色和大背景之间。两块亮度相同的 slate-500 紧挨着,不管怎么转色相都分不清。在相邻区域之间引入一个亮度阶差,整张图表就能扛住所有 CVD 变体。

Achromatopsia 和 cone monochromacy 虽然罕见,但值得专门为它们设计,因为它们会把所有色相差异统统抹平。Achromatopsia 用户感知到的只有亮度,你的色编码 UI 在他们眼里就是一张黑白照。如果你给整个页面套一个 filter: grayscale(1)(在 DevTools 里直接试),设计依然立得住,那就意味着你通过了「颜色不是唯一信号」的最严版本。这是你能跑的最便宜的无障碍测试,而且一翻这个开关,马上就能看出一堆隐藏问题。

审计 Tailwind 与 Material 色板

绝大多数前端工作用的都是现成的色板:Tailwind v4、Material 3、Radix 或 shadcn。这时无障碍问题就变成了「这条色阶从哪一档开始文字变得可读?」,答案比文档里说的更像经验法则。

Tailwind v4 的 slate 色阶在纯白背景下,WCAG 与 APCA 数字大致如下:

Tailwind class近似 hex与白对比AA 正文AAA 正文APCA Lc(近似)
slate-400#94a3b82.56:1约 38 ✗
slate-500#64748b4.76:1约 60 ✗ 正文
slate-600#4755697.58:1约 78 ✓ 正文
slate-700#33415510.35:1约 90 ✓ 正文

几条实战规则:

  • 正文至少要用 slate-600 或更深。 slate-500 能通过 WCAG AA,但过不了 APCA 的正文阈值,合规但读起来累。slate-600 是安全底线。
  • UI 标签和次要文字可以用 slate-500。 UI 组件只需要 3:1,slate-500 的 4.76:1 绰绰有余,而且这种文字通常还有视觉上下文托底。
  • 占位符应用 slate-400 或更浅。 占位符文字作为装饰元素被 WCAG 1.4.3 豁免,前提是字段上方有可见的标签。把标签直接当占位符的写法必须达到正文阈值。
  • slate-100 / slate-200 上用纯黑是浪费墨。 已经 17:1+ 了;考虑改用 slate-700 或 slate-800 作为字色,质感更柔,可读性不掉。

Material 3 用的是类似的色调色板结构。它的 surface-container-high 大约位于 tone 92(很浅),on-surface 大约位于 tone 10(接近黑)。Material 规范保证同一族里任意 on-surface 配任意 surface-* 都能通过 AA。但 on-surface-variant(tone 30)配 surface-container(tone 94)就别没检查就上,这是我亲眼见过被上线的真实漏网案例。

如果手上有一套色板过不了对比度,OKLCH 提供了最干净的修复路径。不要瞎调 hex 码,而是把颜色转到 OKLCH,固定 C(饱和度)和 H(色相),只降 L(亮度),直到对比度通过。因为 OKLCH 的 L 通道是真正感知线性的,品牌识别度能保留下来,对比度同时收紧。HEX 转 OKLCH 工具一步搞定这种转换;姐妹文章《OKLCH 色彩空间详解》把数学细节讲透。

深色模式值得单独说一段。WCAG 2 的对称比率按定义在亮色和深色模式下对同一组合给同样的分数;APCA 因为极性敏感,经常会判定深色模式的正文比同一组 hex 在亮色模式下更难读。在相同数值比率下,浅字深底相对深字浅底总会损失一些感知对比度,这是人眼适应过程中已知的效应。深色模式上线之前,对每一对配色都重新跑一遍 APCA。

对比度检查工具与 CI 工作流

设计师和工程师各有自己钟爱的检查器;真正务实的问题是:你把哪几个工具组合起来塞进了真实工作流。截至 2026 年,这一带的格局如下:

工具WCAG 2APCACVD 模拟色板审计
WebAIM Contrast Checker
Adobe Color
Stark(Figma 插件)
Polypane(浏览器)
Chrome DevTools 取色器✓(实验)
axe DevTools✓(页面级)
Go Tools 颜色转换器✓(8 类)✓(Tints/Shades)

能扛住真实产品压力的工作流大致是这样的:

  1. Figma 阶段:设计师在每个 Frame 上跑 Stark,提前暴露不达标的配色对。Stark 能在 hex 码进入代码库之前抓住最明显的失误。
  2. hex 码移交阶段:工程师把值粘进颜色转换器,一行里就拿到 WCAG 比率 + APCA Lc + 色域分类 + CVD 预览。如果是深色模式或饱和品牌色,双指标能抓住 Stark 可能漏掉的「WCAG 过、APCA 不过」案例。
  3. PR 阶段axe-core/playwright 扫描构建出的页面,针对渲染后的 DOM 检查任何对比度违规,包含动态状态。这能抓到静态设计稿里看不见的焦点环、悬停态、禁用样式问题。
  4. QA 阶段:用 Chrome DevTools 的 Rendering 面板对关键流程做 Protanopia / Deuteranopia / Tritanopia 抽查。DevTools 的取色器在你 hover 任何元素时也会直接给出 WCAG 比率。

Pa11y、Lighthouse CI 和 @axe-core/playwright 都把对比度断言作为无障碍审计的一部分暴露出来。它们当前都不查 APCA,只查 WCAG 2。现实的折中是:「CI 强制 WCAG 2 AA,品牌色和深色模式靠人工再过一遍 APCA Lc 心里有数。」

值得向大型设计系统团队借鉴的一个模式:把对比度检查烤进 token 校验环节,而不是只放在页面级 QA。如果你的设计 token 是从一个源文件(JSON、YAML 或 TypeScript 模块)编译出来的,加一个脚本枚举系统允许的每一个 --text-* × --surface-* 组合,断言最低 WCAG 比率。脚本毫秒级跑完,能在某人改动 token 值时立刻发现回归,输出的对比度矩阵还能顺便给设计团队当文档用。检查独立于任何渲染页面,只看 token,所以能在任何 UI 上线之前就抓住问题。

工作流中临时做格式互转的部分(比如在 hex、RGB、HSL、OKLCH 之间来回调试),HEX 转 RGBHEX 转 HSLHEX 转 OKLCHRGB 转 HEX 这几个 spoke 工具覆盖了工具链可能需要的任何颜色格式往返。

常见错误与修复方法

跑了多年无障碍审计,总有同样六类失误反复出现。每一类都有干净的修法:

  1. 占位符用浅灰色。 白底上的 #999999 只有 2.85:1,AA 不通过。要么加深到 #666666(5.74:1,过 AA),更好的做法是干脆把「占位符当标签」改成在字段上方挂一个一直可见的标签。占位符不应该承担传达信息的职责。

  2. 品牌橙按钮配白字。 白底上的 #FFA500 仅 1.97:1,AA 惨败。保留品牌的修法是反转对比方向:橙色背景上压深字(例如 #451a03),或者保留白字但把按钮压暗到深饱和的棕橙。上线前用颜色转换器再验一遍。

  3. 深色模式下的亮蓝链接。 #3b82f6#000000 是 5.71:1,WCAG AA 通过,但 APCA Lc 约 65,低于正文 Lc 75 的阈值。改用 OKLCH,把 L 从约 0.63 抬到 0.75,C 和 H 保持不变;你会落在 #7aa5f8 附近,APCA Lc 顺利越过 80,色相完全没动。

  4. 禁用文字用 #CCCCCC 白底上仅 1.61:1。WCAG 1.4.3 豁免的是纯装饰文字,禁用状态下的 UI 控件不是装饰,它在传达「这个目前不可用」。除了灰字之外,还要配非颜色信号(删除线、锁形图标、「Disabled」tooltip),让色觉异常或低视力用户也能识别状态。

  5. 图标只靠色相区分。× 和绿 没问题,因为形状已经把它们区分开了;但红圆点对绿圆点就不行。形状和颜色一起用,颜色转换器的 CVD 预览能让失败案例在一秒内现形。

  6. 渐变背景上的文字。#3b82f6 渐变到 #a78bfa 的背景上压白字,中段对比度过得去,但接近薰衣草紫的一端就过不了。修法是按渐变中最差的一点校验对比度,或者叠一层半透明的深色蒙版,让有效背景亮度始终低于某个已知阈值。

每条修复都只要几分钟,避免掉的审计周期是以周计的。

FAQ

WCAG AA 对比度是什么意思?

WCAG AA 要求正文与背景之间至少 4.5:1,大号文本(≥ 18pt 常规字重或 ≥ 14pt 粗体)和 UI 组件(如表单边框)至少 3:1。AA 在 ADA、EAA、Section 508 下是法律底线,大多数商业网站都瞄准 AA,因为它在不把品牌色压向灰阶的前提下满足了监管要求。

AAA 需要多少对比度?

WCAG AAA 要求普通正文至少 7:1,大号文本至少 4.5:1。AAA 更多被推荐给医疗、教育和政府类站点,这些受众覆盖更高的无障碍需求。品牌色想通过 AAA 经常需要扁平化到接近灰阶的程度,这也是很多商业产品停在 AA 的原因。

APCA 是什么?它是 WCAG 3.0 吗?

APCA(Advanced Perceptual Contrast Algorithm)是 WCAG 3 Silver 项目下的候选算法,由 Andrew Somers(Myndex)设计。它使用 -108 到 +108 的极性敏感 Lc 分数,而不是对称比率。截至 2026 年,WCAG 3 仍处于早期草案,APCA 还没有被正式确立——你今天必须达成的监管标准依然是 WCAG 2.1 / 2.2 AA。

深色模式对对比度无障碍有帮助吗?

有时候有,但不会自动生效。WCAG 2 的对称比率在亮色和深色模式下对同一组合给同样的分数,但 APCA(极性敏感)常常会判定深色模式下的正文比相同 hex 在亮色模式下更难读。上线之前请同时用 WCAG 和 APCA 跑一遍深色模式;浅字深底的感知对比度损失,对称比率公式看不到。

为什么我的品牌色过不了 WCAG AA?

饱和的中等亮度颜色(绝大多数橙色、黄色、酸橙绿、浅蓝)相对亮度太接近白色,过不了 4.5:1。修法:把品牌色留给点缀和大标题,正文文本用同一色相家族里更暗的色调。借助 OKLCH 在不改色相的情况下降低 L 通道,颜色转换器一步就能找到最接近的合格色调。

WCAG 2 比率和 APCA 分数可以互换吗?

不能。WCAG 2 返回一个对称比率(1–21);APCA 返回带极性符号的 Lc 分数(-108 到 +108)。两者关系非线性:一对在 WCAG 中是 4.5:1 的颜色,在 APCA 中可能是 Lc 60 也可能是 Lc 75,取决于谁压在谁上面。把它们当成两个独立的检查,而不是互为翻译。

小型 UI 图标可以用颜色对比来满足无障碍吗?

可以,但有前提。WCAG 2.1 §1.4.11 要求 UI 组件和图形对象至少 3:1。配有可见文字标签的装饰图标,对比度要求会放宽——意思由文字承担。独立图标(比如没有标签的搜索放大镜),就要严格保证对背景至少 3:1。

不模拟的话怎么测试色觉异常?

用 Chrome DevTools → Rendering → 「Emulate vision deficiencies」可以模拟 Protanopia、Deuteranopia、Tritanopia 和 Achromatopsia。再配合颜色转换器的 8 类 CVD 预览覆盖 anomalous trichromacy 变体(Deuteranomaly 是最常见的,占男性 5%)。如果是审计报告,把每一种模拟下的截图都抓下来,方便审阅者一眼看出失败模式。

总结

五条结论:

  • AA 4.5:1 是法律底线。 所有正文都要打到,否则等着合规来打你。
  • AAA 7:1 用于医疗、教育、政府。 大多数商业品牌主动把目标停在 AA。
  • APCA Lc 是真实可读性的直觉检查。 与 WCAG 2 并行跑,深色模式和饱和品牌色尤其需要。
  • 颜色永远不是唯一信号。 每一处颜色提示都配上形状、文字或图样;光是 Deuteranomaly 就占男性用户的 5%。
  • OKLCH 的 L 是对的旋钮。 颜色对比度不够时,降 L(不是 S,也不是 B),就能在不漂色相的前提下修好。

把任意两个十六进制颜色粘进颜色转换器,就能在同一行里看到 WCAG 比率、APCA Lc、色域分类和 8 类 CVD 预览,省下来回切换工具的时间。