如何挑选无障碍的颜色组合
颜色选择看起来像审美决定,实际却像法律决定。自 2021 年以来,每年大约有 4000 起 Web 无障碍诉讼打到美国被告头上,而颜色对比度不足是 WCAG 类诉讼里被最常引用的三大问题之一(另外两个是缺少 alt 文本和未标注的表单字段)。好消息是:对比度是三者中最简单可修的,一个比值是数字,WCAG 阈值也是数字,几秒钟就能算出。坏消息是:「无障碍」不止头条比值这么简单,色盲、焦点指示器、深色模式、token 化都重要,一个每种正文样式都拿到 4.5:1 的调色板,仍可能让真实用户用不了。
数字颜色无障碍简史
颜色对比度作为成文标准,起源于 W3C 的 Web Accessibility Initiative 在 1997 年的首批工作。最初的 Web Content Accessibility Guidelines 1.0(1999 年 5 月)以定性方式建议「足够的对比度」,没有给出具体数字。WCAG 2.0(2008 年 12 月)引入了我们现在熟悉的相对亮度公式和 AA 级 4.5:1 比值,源自 Lighthouse International 关于年长戴老花镜的用户能在屏幕上舒服阅读什么的研究。
法律分量是后来才有的。美国 Rehabilitation Act 第 508 条在 2018 年引用 WCAG 2.0;ADA 在 2019 年 1 月 15 日 Ninth Circuit 关于 Robles v. Domino's 的判决(最高法院 2019 年 10 月拒绝受理上诉)之后,被美国法院解读为在第三章下覆盖数字无障碍。欧洲无障碍法案(European Accessibility Act)于 2025 年 6 月 28 日生效,要求公共部门和许多私营公司面向消费者的数字服务符合 WCAG 2.1 AA。实务中,4.5:1 正文 + 3:1 大字 + 3:1 UI 组件,是任何今天在建的公开网站的事实底线。
科学也在持续演进。WCAG 2.1(2018)增加了 3:1 非文本对比度规则。Andrew Somers 为 WCAG 3 开发的 APCA 算法对亮度感知建模更准确,对非常深和非常浅的搭配给出不同的数字;它在 2026 年仍是 Editor's Draft,不是标准,所以大多数法规仍引用 WCAG 2.x。Bjorn Ottosson 的 OKLAB 和 OKLCH(2020)给设计师提供了一个感知均匀的色彩空间,使生成无障碍的色阶比在 HSL 或 RGB 里容易得多。
「无障碍颜色」究竟意味着什么
有四件事重要,不只是那一个比值:
- 前景对背景的对比度。头条数字。正文需要 4.5:1,大字 3:1,UI 控件与焦点指示器对相邻颜色 3:1。
- 色盲。约 8 % 的男性和 0.5 % 的女性看到的颜色比设计假定的要少。主要三类:protanopia 与 deuteranopia(红绿,最常见)、tritanopia(蓝黄)。
- 颜色永远不是唯一信号。WCAG 1.4.1 禁止仅靠颜色传达意义。红色「错误」边框还需要图标或文字标签。
- 焦点指示器。键盘用户需要看到焦点在哪。WCAG 2.4.7 要求可见的焦点指示;2.4.11(WCAG 2.2)更新要求至少 2 个 CSS 像素粗,且对相邻颜色 3:1 的对比度。
如何一步步挑选无障碍颜色
- 从语义 token 开始,不要从原始颜色开始。定义
text-primary、text-secondary、surface-default、surface-elevated、border-default、accent-primary、accent-danger等。 - 挑选亮度级。用 OKLCH 亮度值构造 5 到 9 级的尺度,每级与下一级的感知差恒定。
- 在每个亮度级挑选色相。取品牌色相,再挑互补或强调色相,保持相近的 chroma。
- 计算对比度。每对相邻 token 需要正确的比值。正文对默认面板:4.5:1。禁用文本若要可读,至少 3:1。
- 跑色盲模拟器。取关键画面,用 protanopia、deuteranopia、tritanopia 模拟器分别重渲染。
- 用真实辅助技术测试。Mac VoiceOver、NVDA、JAWS、TalkBack 都应能不依赖颜色线索地导航。
- 在颜色承载意义之处,都加上非颜色信号。错误/成功/警告的图标,正文链接的下划线,图表系列的样式图案。
- 把 token 文档化。一份 Figma 库、一页 Storybook,或一个静态的设计系统站。
对比度参考
| 搭配 | WCAG 2.1 最低 | AA 级 | AAA 级 |
|---|---|---|---|
| 正文(小于 18pt regular 或 14pt 粗体) | 4.5:1 | 4.5:1 | 7:1 |
| 大字(18pt regular 或 14pt 粗体) | 3:1 | 3:1 | 4.5:1 |
| UI 组件(表单边框、切换状态、焦点) | 3:1 | 3:1 | 不适用 |
| 图形对象(承载意义的图标) | 3:1 | 3:1 | 不适用 |
| Logo 内的文字 | 豁免 | 豁免 | 豁免 |
| 禁用控件 | 豁免 | 豁免 | 不适用 |
| 装饰性文字 | 豁免 | 豁免 | 豁免 |
色盲类型与检查方法
| 类型 | 发病率 | 看到更少的 | 常见失败 |
|---|---|---|---|
| Protanopia | 男性约 1 % | 红色 | 红色错误与绿色成功无法区分 |
| Deuteranopia | 男性约 5 % | 绿色 | 同上:红绿混淆 |
| Tritanopia | 约 0.005 % | 蓝色 | 蓝黄无法区分 |
| Achromatopsia | 约 0.003 % | 所有颜色 | 只看到灰阶亮度 |
| 异常三色觉 | 约 5 % | 某通道灵敏度降低 | 细微的颜色差异融合 |
常见陷阱
- 在 HSL 或 RGB 里设计。HSL 里相等的数值步长产生不相等的感知步长。OKLCH 修复了这一点。
- 仅靠颜色表达状态。红绿表错与对:8 % 用户分辨不出。加图标或文字标签。
- 纯黑配纯白。
#000配#FFF得 21:1,但长时间阅读刺眼。改用近黑配近白。 - 品牌色暴政。把品牌红当神圣,在品牌白上以 2.1:1 用,「因为是品牌」。刷新品牌调色板。
- 深色背景上消失的焦点指示器。深蓝按钮上的 2px 蓝色环可能看不见。在每个可能出现的表面上都测一下焦点环。
- placeholder 文字对比度不足。
placeholder=文本浏览器默认按约 40 % 不透明度渲染,白底很容易跌破 4.5:1。 - 表单字段轮廓太淡。白底上 1px 灰色边在 1.2:1 对比下不符合 WCAG 1.4.11。调到 3:1 或加粗。
- 仅靠颜色变化的悬停态。某些指针设备不产生悬停。配合轻微阴影或位移变化。
- 深色模式靠简单反相做。反相产生饱和的深色,会刺眼。深色模式要有自己的设计过程,带去饱和的强调色。
- 自动生成在图像上的文字。渲染在用户上传图像上的文字无法保证对比度。加半透明背板或文字阴影。
替代算法与标准
| 算法 | 年份 | 状态 | 优势 |
|---|---|---|---|
| WCAG 2.x 对比度 | 2008 | 大多数法规要求 | 数学简单,工具齐全 |
| APCA | 2020 | WCAG 3 Editor's Draft | 在感知亮度上更准确 |
| ISO 9241-302 | 2008 | 工作站人因标准 | 面向硬件,非常严格 |
| Lighthouse 对比度警告 | 2018 | Chrome DevTools | 免费,在浏览器中 |
| axe-core | 2015 | 开源库 | 自动化测试的行业标准 |
今天的合规工作,WCAG 2.1 AA 是底线。APCA 随着 WCAG 3 成熟值得跟踪;许多设计系统团队已经同时报告两个数字。
挑选无障碍颜色的工具
| 工具 | 用途 | 优势 |
|---|---|---|
| 颜色对比度检查器(浏览器) | 给一对前景/背景打分 | 即时,不上传,任何设备都能访问 |
| 无障碍调色板生成器 | 构建恒定 chroma 的完整亮度阶梯 | 用 OKLCH 保证感知均匀 |
| 色盲模拟器 | 按色盲所见重渲染画面 | 上线前发现红绿问题 |
| Chrome DevTools Lens | 就地检视对比度和色盲 | 浏览器内建 |
| WebAIM Contrast Checker | 经典 WCAG 2 参考 | 可信,广为引用 |
| Stark(Figma 插件) | 在设计阶段审计 Figma 设计 | 在设计期就发现问题 |
| axe DevTools(浏览器) | 自动化 WCAG 扫描 | 行业标准 |
| Tailwind、Radix、Open Props 色阶 | 预测试的 OKLCH 调色板 | 由设计团队精选的无障碍 |
隐私与工具
颜色对比度检查器、无障碍调色板生成器和色盲模拟器都完全运行在你的浏览器里。你挑选或粘贴的颜色由你设备上的 JavaScript 处理,结果渲染到页面,什么都不会发送到服务器。没有遥测、没有对输入的分析、没有第三方脚本。对尚未公开的品牌色、内部产品调色板、或处于禁运期的设计,这种严格本地的流程,就是「把你未发布的品牌资产交给陌生人的设计工具」和「谁都不交」之间的差别。整套工具一旦页面加载完成就可以离线运行,你可以断网再重新比一对颜色来验证。
常见问题
What contrast ratio does WCAG require?
WCAG 2.1 Level AA requires at least 4.5:1 for normal body text and 3:1 for large text (18 pt regular or 14 pt bold). Level AAA raises that to 7:1 for normal text and 4.5:1 for large text. Non-text UI components and graphical objects need 3:1 against adjacent colors.
Are WCAG contrast ratios scientifically accurate?
They are based on the WCAG 2.0 algorithm from 2008, which compares the relative luminance of two colors using the sRGB color space. The formula is imperfect for very dark and very light combinations and for some color hues; the APCA (Accessible Perceptual Contrast Algorithm) being developed for WCAG 3 produces more perceptually accurate results. For 2026 work, WCAG 2.x is still the standard most regulations cite.
How do I check whether my colors work for color-blind users?
Run them through a color-blindness simulator that converts your palette to what someone with protanopia, deuteranopia, or tritanopia sees. About 8% of men and 0.5% of women have some form of color vision deficiency, so this matters.
Should I use the same color palette for light and dark mode?
Usually not. Dark mode needs slightly desaturated colors at the same hue, otherwise vivid colors that look fine on white become eye-strain on black. Define semantic tokens (text-primary, surface-secondary) and map them to different physical colors per mode.
What does OKLCH have to do with accessibility?
OKLCH is a perceptually uniform color space (Bjorn Ottosson, 2020) where equal numerical changes produce equal perceptual changes. That makes it much easier to generate accessible color scales because you can step the lightness in equal increments and the perceived brightness step is consistent, which is hard to do in HSL or RGB. CSS supports OKLCH directly since 2023 in all major browsers.