12k
All articles

如何检查 WCAG 的颜色对比度

了解如何用合适的工具和标准检查WCAG颜色对比度,涵盖文本、UI组件、焦点指示和链接。

OpenReplay Team
OpenReplay Team
如何检查 WCAG 的颜色对比度

要检查 WCAG 的颜色对比度,需比较前景文本与其背景的相对亮度(relative luminance),然后确认得出的比值是否满足该元素类型对应的阈值:在 AA 级下,普通文本为 4.5:1,大号文本为 3:1,非文本 UI 为 3:1。

我们大多数人都是吃过亏才学会这一点的——上线了一个浅灰色标签,在自己的屏幕上看着挺好,两个 sprint 之后却在审计中被判不合格。这个值不需要你手工计算:检查工具用两个十六进制值几秒钟就能算出来。本指南将给出确切的阈值、测量比值的最快方法、大多数团队踩过的坑,以及那些超出正文文本范围、延伸到 UI 组件、焦点指示器和以颜色编码含义的相关规则。

要点速览

  • WCAG AA 级要求普通文本对比度为 4.5:1,大号文本为 3:1;AAA 级则分别提高到 7:1 和 4.5:1。
  • 非文本元素(输入框边框、按钮轮廓、有实际含义的图标、图表分段以及焦点指示器)在 WCAG 1.4.11 下需要相对相邻颜色达到 3:1。
  • “大号文本”指 18pt(约 24px)及以上,或 14pt 粗体(约 18.66px)及以上;小于此尺寸的文本一律适用 4.5:1 的普通文本阈值。
  • 最常见的失败案例是浅灰色正文:白底上的 #999999 大约只有 2.85:1,不合格;而 #595959 可达 7:1,同时通过 AA 和 AAA。
  • WCAG 2.2 是当前标准,但其对比度最低要求与 2.1 和 2.0 完全一致。这些数值从未改变。

WCAG 要求多大的对比度?

对比度衡量的是两种颜色之间的亮度差异。下限是 1:1,即前景与背景颜色完全相同时的情况;上限是 21:1,即纯黑对纯白。WCAG 的计算公式为 (L1 + 0.05) / (L2 + 0.05),其中 L1 和 L2 分别是较亮和较暗颜色的相对亮度。以下是所有检查工具都会执行的阈值:

元素AA 级AAA 级成功准则
普通文本4.5:17:11.4.3 / 1.4.6
大号文本3:14.5:11.4.3 / 1.4.6
非文本(UI、图形、焦点)3:11.4.11

在 AA 级下,普通文本为 4.5:1,大号文本为 3:1;AAA 级将这两个数值提高到 7:1 和 4.5:1。什么算“大号”取决于字号和字重:18pt(约 24px)及以上,或者在粗体情况下 14pt(约 18.66px)及以上。WebAIM 对比度检查器正是按照这些阈值给出结果的。一条判断线索足以覆盖大多数情形:文本是大号吗?→ 3:1;否则 → 4.5:1。

有个值得澄清的误区:2023 年 10 月发布的 WCAG 2.2 增加了焦点外观方面的指导,但并未改动对比度最低要求。后续版本只会新增成功准则,而不会改写已有准则(4.1.1 Parsing 是唯一例外),因此 4.5:1 / 3:1 / 7:1 在 2.0、2.1 和 2.2 中始终保持不变。低对比度仍是网络上最常见的无障碍缺陷。2026 年的 WebAIM Million 报告发现,前一百万个首页中有 83.9% 存在低对比度文本。

如何检查颜色对比度?

最快的工作流程是:取得两个渲染后的十六进制值,粘贴到检查器中,读取通过/不通过结果。要取渲染后的颜色,而非设计文件中的数值:叠加层、渐变和透明度都会改变用户实际看到的效果。

  • WebAIM Contrast Checker:粘贴前景和背景的十六进制值。你会得到比值以及五项判定结果,因为普通文本和大号文本各自在 AA 和 AAA 下判定,非文本元素还有单独的 AA 一行。如果这组颜色不达标,可以用 Lightness 滑块微调任一颜色直到通过,正如 WebAIM 的工具使用说明所展示的那样。
  • TPGi Colour Contrast Analyser:适用于 Windows 和 macOS 的桌面应用。可用取色器直接从屏幕上拾取任一颜色,以 hex、RGB、HSV 或 HSL 输入数值,为前景设置 alpha 值,并拖动滑块让不合格的配色通过。它还能通过八种视觉缺陷设置预览你的配色。
  • Chrome DevTools:检查元素,从其 color 声明旁的色块打开 Color Picker,展开 Contrast ratio 区域。它会报告该配色是否通过 AA 和 AAA,提供一个可直接应用合格数值的 Use suggested color 按钮,并在色调预览中以线条标出 AA 和 AAA 的分界,方便你手动将取色点拖到线下方。
  • Firefox:打开 DevTools → Accessibility 面板 → 选中节点 → 查看其对比度及通过/不通过状态。

若要做整页审计,可运行 WAVEaxe DevTools 或 Lighthouse。WAVE 会读取样式中的文本与背景颜色,捕捉大多数低于 AA 4.5:1 线的正文文本,并对大号文本套用较低的 3:1 阈值。它无法判断的是图片上的文字、alpha 合成,以及 hover 和 focus 状态,因此重要组件仍需手动验证。

常见的对比度失败案例及修复方法

大多数失败都出自少数几个惯犯,而且修复方法快捷、可验证。

白底浅灰文字。 白底上的 #767676 是仍能通过 AA 的最浅灰色,正好 4.5:1;而 #999 只有 2.85:1,不合格。把正文文本加深到 #595959,它恰好落在 7:1,AA 和 AAA 双双通过。

/* FAIL: ~2.85:1 */  color: #999999; background: #fff;
/* PASS: 7:1 */      color: #595959; background: #fff;

占位符文本。 把 placeholder 设置为 40–50% 不透明度是导致 1.4.3 不合格的常见原因,因为背景会透出来,把比值拉低到 4.5:1 以下。应该给它一个实打实的十六进制值 #767676 或更深。此外,凡是用户必须读到的信息都应使用常驻的 <label>,因为占位符在输入时会消失。

仅靠颜色区分的链接。 加上 text-decoration: underline,让链接不再只靠色相来区分。一旦去掉下划线,你就要承担额外的要求:链接文本需要相对周围正文文本达到 3:1,此外两种颜色都还得相对背景达到 4.5:1。

图片上的文字。 照片各处亮度不一,同一段文字在某个区域合格,换个区域就不合格。加一层半透明遮罩:

.hero {
  background:
    linear-gradient(rgba(0,0,0,.6), rgba(0,0,0,.6)),
    url("hero.jpg");
}
.hero-text { color: #fff; } /* now has guaranteed contrast */

超越文本:UI 组件、焦点与颜色的使用

对比度规则不止适用于段落。成功准则 1.4.11 为控件以及读者理解内容所必需的图形部分设定了 3:1 的下限,测量对象是紧邻它们的颜色。输入框边框、按钮轮廓、承载含义的图标以及图表系列都在其列。状态也算数,但有个前提说明:默认状态需要达到 3:1,且任何状态都不得使组件低于该值,不过你额外叠加的 hover 效果本身并不受 3:1 约束,只要它没有抹掉控件原有的对比度即可。

焦点指示器是准则编号最容易混淆的地方,所以要精确对应。焦点可见性属于 2.4.7 Focus Visible。指示器的 3:1 对比度来自 1.4.11 Non-text Contrast,而不是 2.4.11——后者是 Focus Not Obscured (Minimum),关注的是叠加层遮挡获得焦点的元素。AAA 级的 2.4.13 Focus Appearance 则在此基础上追加了最小尺寸和状态变化对比度的要求。

最后,WCAG 1.4.1 Use of Color(A 级)意味着绝不能仅靠颜色传达含义:红/绿状态要搭配文字标签或图标,链接要加下划线。有一条豁免需要记住:非活动(禁用)组件不受非文本对比度和对比度最低要求的约束,但保持其可读性仍然是比把它灰到看不见更好的用户体验。

把对比度纳入你的工作流

在上线之前就把对比度问题抓出来。设计阶段用 Figma 中的 Stark 之类的插件检查,然后把结果固化到 token 层,为每种颜色标注其比值:

:root {
  --text-primary:   #171717; /* 18.8:1 — headings, body */
  --text-secondary: #595959; /* 7:1  — secondary text */
  --border-input:   #767676; /* 4.5:1 — meets 1.4.11 */
  --border-subtle:  #d4d4d4; /* 1.6:1 — decorative only */
}

正文文本应当远高于最低要求(10:1 以上比较从容),而次级文本和大号文本可以保持在 4.5:1,边框保持在 3:1。在 Chrome DevTools → Rendering → Emulate vision deficiencies 中做色盲测试,确认在没有颜色的情况下含义依然成立。然后实现自动化:在 CI 中运行 axe 或 Lighthouse,让对比度回归导致构建失败,而不是流向用户。另外,深色模式要单独过一遍:亮度反转会破坏在浅色模式下通过的比值,因此每个主题下的每个 token 都要重新计算。

对比度是最容易修复、也最容易预防的无障碍问题之一。选一款检查器,把阈值固化为 token,在 CI 中接入自动扫描,上面这些失败就不会再流入线上。今天就先对照 4.5:1 和 3:1 这两条线,审计你现有的正文文本和焦点样式吧。

常见问题

WCAG 对比度衡量的是色相和饱和度,还是只有明度?

对比度只衡量相对亮度(即每种颜色的感知明亮程度),不涉及色相或饱和度。这就是为什么两种看起来差别很大的颜色(例如绿底上的红字)在亮度接近时依然可能不合格。比值由较亮和较暗的亮度值按 (L1 + 0.05) / (L2 + 0.05) 计算得出,因此仅靠色相传达的含义由 WCAG 1.4.1 Use of Color 单独规范。

WCAG 1.4.11 Non-text Contrast 与 2.4.11 Focus Not Obscured 有什么区别?

WCAG 1.4.11 Non-text Contrast(AA 级)要求 UI 组件和有含义的图形(包括焦点指示器)相对相邻颜色达到 3:1 的对比度。WCAG 2.4.11 Focus Not Obscured(Minimum,AA 级)是 WCAG 2.2 中的新准则,与对比度无关:它要求获得焦点的元素不被作者创建的内容(如吸顶导航或叠加层)完全遮挡。对比度归 1.4.11 管;被遮挡时的可见性归 2.4.11 管。

为什么同一段文字在设计文件里对比度合格,在浏览器里却不合格?

设计文件插件检查的是你指定的纯色值,而浏览器会对渲染结果进行合成。不透明度、半透明叠加层、渐变、背景图和混合模式都会改变用户实际看到的亮度。设置为 50% 不透明度的占位符,或者叠在照片上的文字,在设计稿中可能合格,渲染之后却不合格。请始终从 DevTools 或屏幕取色工具中采集渲染后的十六进制值,而不要轻信源文件中的颜色。

禁用状态的按钮和非活动控件需要满足 WCAG 对比度最低要求吗?

不需要。WCAG 1.4.3 Contrast (Minimum) 明确豁免了非活动的用户界面组件,禁用元素同样被排除在 1.4.11 非文本对比度要求之外。这意味着一个灰掉的禁用按钮不会在自动化对比度审计中被判不合格。保持禁用控件可读依然是更好的可用性做法,因为完全看不见的控件会让用户困惑,但就该状态而言,这并非 WCAG 合规要求。

Digital experience platform

Truly understand users experience

See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.