色盲友好配色怎么做?WCAG 对比度与无障碍设计指南
你做的表单,必填项错误提示是红色边框,成功提示是绿色对勾。对于每 12 个男性用户里的 1 个来说,这两种颜色长得几乎一模一样——他们不知道自己填错了。同样,那个用 #999999 灰字写在白底上的说明文字,对比度只有 2.85:1,远低于 WCAG 要求的 4.5:1,在户外强光下几乎看不清。这篇文章讲清楚色觉异常到底是怎么回事、WCAG 对比度怎么算,以及六条能立刻用上的配色准则。
色觉异常有哪几种,多少人受影响
人眼视网膜上有三种视锥细胞,分别对长波(L,红)、中波(M,绿)、短波(S,蓝)敏感。色觉异常就是其中某一类视锥细胞缺失或功能偏移。
| 类型 | 学名 | 缺陷 | 男性比例 | 女性比例 |
| 绿色弱 | Deuteranomaly | M 视锥偏移 | 约 5% | 0.35% |
| 红色弱 | Protanomaly | L 视锥偏移 | 约 1.3% | 0.02% |
| 红色盲 | Protanopia | L 视锥缺失 | 约 1.0% | 0.01% |
| 绿色盲 | Deuteranopia | M 视锥缺失 | 约 1.2% | 0.01% |
| 蓝黄色盲 | Tritanopia | S 视锥缺失 | 约 0.01% | 0.01% |
| 全色盲 | Achromatopsia | 三类均失效 | 约 0.003% | 0.003% |
合计:男性约 8%,女性约 0.5%。 换算一下,一个日活 10 万、男女各半的产品,大约有 4250 个用户存在色觉异常。这个数字比很多产品的付费用户还多。
男女比例悬殊 16 倍源于遗传方式。 红绿色觉基因位于 X 染色体且为隐性:男性只有一条 X,携带缺陷基因就会发病;女性需要两条都有缺陷,概率是男性的平方级。所以面向男性为主的产品(游戏、汽车、工具类、B 端后台)色觉友好的收益更高。
注意「色弱」和「色盲」的区别:色弱不是看不见颜色,而是分辨阈值变高。绿色弱的人能看到红和绿,只是当两者饱和度或明度接近时区分不出来,所以往往到成年才发现自己有问题。
三类色盲看到的世界
红色盲(Protanopia):红色的感知亮度大幅下降。纯红 #FF0000 在他们眼里是暗褐色,接近黑色。红和绿都退化成相近的黄褐色调,紫色因为失去红色成分而变成蓝色。危险信号用纯红是最糟糕的选择,因为对他们来说红色不仅难辨认,还很暗。
绿色盲(Deuteranopia):最常见的一类。红绿同样混淆,但和红色盲不同的是红色的亮度感知基本正常。他们看到的红和绿都偏向米黄/卡其色。绿色和棕色、粉色和灰色也难以区分。
蓝黄色盲(Tritanopia):极其罕见,蓝绿混淆、黄粉混淆,蓝色偏绿、黄色偏粉白。因为不是伴 X 遗传,男女比例相当。
三类色盲有一个共同点:明度(亮度)感知基本正常。 这是无障碍配色最重要的一条线索——用明度差替代色相差,就能让所有人都区分开。 一个深蓝和一个浅灰,无论哪种色觉都能分辨;而饱和度和明度都接近的红与绿,对 8% 的男性用户来说就是同一个颜色。
想直观看看自己的配色在三类色觉下长什么样,把设计稿的主色丢进色盲模拟器看一眼比任何理论解释都有说服力,通常第一次看到结果的设计师都会当场改方案。
WCAG 对比度:公式和标准
WCAG(Web Content Accessibility Guidelines)用一个明确的数值来衡量前景色和背景色的可读性。
第一步,把 sRGB 值线性化。 屏幕上的 RGB 值经过了伽马编码,要还原成线性光强:
对 R、G、B 每个通道(先归一化到 0~1):
if c ≤ 0.03928: c_lin = c / 12.92
else: c_lin = ((c + 0.055) / 1.055) ^ 2.4
第二步,算相对亮度 L:
L = 0.2126 × R_lin + 0.7152 × G_lin + 0.0722 × B_lin
注意这三个系数:绿色权重 0.7152,是蓝色 0.0722 的十倍,这符合人眼对绿光最敏感的生理事实,也解释了纯绿色在白底上为何几乎看不清。
第三步,算对比度:
对比度 = (L_亮 + 0.05) / (L_暗 + 0.05)
结果范围是 1:1(完全相同)到 21:1(纯黑对纯白)。加 0.05 是为了模拟屏幕表面的环境光反射。
WCAG 定义了两档合规标准:
| 级别 | 正文(<18pt) | 大字(≥18pt 或 ≥14pt 粗体) | 图标/表单边框 |
| AA(法规常用底线) | 4.5:1 | 3:1 | 3:1 |
| AAA(更高要求) | 7:1 | 4.5:1 | — |
换算成常见单位:18pt ≈ 24px,14pt 粗体 ≈ 18.66px 粗体。
来看几个真实数值,很多「看起来还行」的配色其实是不合规的:
| 前景色 | 背景 | 对比度 | AA 正文 | AAA 正文 |
#000000 纯黑 | 白 | 21:1 | ✅ | ✅ |
#333333 深灰 | 白 | 12.6:1 | ✅ | ✅ |
#767676 中灰 | 白 | 4.54:1 | ✅ 刚好 | ❌ |
#777777 中灰 | 白 | 4.48:1 | ❌ 差一点 | ❌ |
#999999 浅灰 | 白 | 2.85:1 | ❌ | ❌ |
#FF0000 纯红 | 白 | 4.00:1 | ❌ | ❌ |
#00FF00 纯绿 | 白 | 1.37:1 | ❌ 几乎不可读 | ❌ |
#0000FF 纯蓝 | 白 | 8.59:1 | ✅ | ✅ |
#28A745 常用「成功绿」 | 白 | 3.13:1 | ❌ | ❌ |
#DC3545 常用「危险红」 | 白 | 4.53:1 | ✅ 刚好 | ❌ |
这张表有三个很值得说的点。
第一,#777777 和 #767676 只差 1,却一个不合规一个合规。 这说明 4.5:1 附近的取色必须用工具算,不能靠眼睛。很多设计规范里的次要文字色就卡在这条线的错误一侧。
第二,UI 框架的默认「成功绿」普遍不合规。 Bootstrap 的 #28A745 在白底上只有 3.13:1,作按钮背景色勉强够用,直接当文字色就不达标。
第三,纯绿色是配色里的陷阱。 因为绿色的亮度权重高达 0.7152,#00FF00 在白底上对比度只有 1.37:1,基本等于看不见。需要绿色文字时必须大幅压暗,#008000 能到 5.14:1 才算过关。取色时用对比度检测工具输入前景背景色直接看数值和 AA/AAA 判定,比事后返工便宜得多。
为什么「红色表示错误、绿色表示成功」是糟糕的设计
这套配色几乎是所有 UI 框架的默认约定,问题在于它把唯一的信息载体压在了色相上,而色相恰恰是 8% 的男性用户区分不了的那个维度。
具体来看它踩了三个雷:
第一,红和绿是红绿色盲最难分辨的一对。 在绿色盲眼中,#DC3545(危险红)和 #28A745(成功绿)都会退化成相近的黄褐色。两个颜色的明度也很接近(相对亮度 0.182 vs 0.285),连明度线索都提供不了。
第二,很多实现里除了颜色没有任何其他区别。 一个只改变边框颜色的表单输入框,对色觉异常用户来说就是「什么都没发生」。这直接违反 WCAG 2.1 的 1.4.1 条款(Use of Color):颜色不能作为传达信息的唯一视觉手段。
第三,红绿的文化含义并非全球通用。 部分东亚金融市场红涨绿跌,和欧美恰好相反,国际化产品的涨跌色最好做成可切换配置。
改法成本极低:给成功状态加 ✓ 图标,错误状态加 ✕ 或 ⚠,再补一句文字说明。颜色由此变成冗余的强化信号而非唯一信号。
常见配色在三类色盲下的可辨识度
下面这张表列出常见的成对配色在三类色觉异常下能否区分,可以直接当选色参考。
| 配色组合 | 红色盲 | 绿色盲 | 蓝黄色盲 | 建议 |
红 #E53935 / 绿 #43A047 | ❌ | ❌ | ✅ | 绝对避免 |
绿 #43A047 / 棕 #6D4C41 | ❌ | ❌ | ✅ | 避免 |
黄 #FDD835 / 亮绿 #C0CA33 | ❌ | ❌ | ⚠️ | 避免 |
红 #E53935 / 黑 #000000 | ⚠️ 红显著变暗 | ✅ | ✅ | 谨慎 |
蓝 #1E88E5 / 紫 #8E24AA | ⚠️ | ⚠️ | ✅ | 谨慎 |
蓝 #1E88E5 / 黄 #FDD835 | ✅ | ✅ | ❌ | 可用(罕见类型除外) |
蓝 #1E88E5 / 橙 #FB8C00 | ✅ | ✅ | ✅ | 首选 |
深蓝 #1565C0 / 浅灰 #BDBDBD | ✅ | ✅ | ✅ | 首选(明度差大) |
黑 #000000 / 白 #FFFFFF | ✅ | ✅ | ✅ | 永远安全 |
「蓝—橙」是无障碍配色的黄金组合。 这两个颜色在色相环上接近对立,且分别落在 S 视锥和 L/M 视锥的敏感区,三类色觉异常都能区分。数据可视化领域广泛使用的 Okabe-Ito 调色板和 ColorBrewer 的 Blue-Orange 系列,用的都是这个原理。需要用颜色区分类别时,先考虑蓝橙,再考虑蓝黄,最后才是别的。
六条实操准则
一、不要只靠颜色传递信息。 这是 WCAG 1.4.1,也是最重要的一条。图表的折线除了颜色不同,还要用实线/虚线/点线区分;柱状图用不同填充纹理;地图用不同的形状标记。一个快速自检方法:把界面截图转成灰度,如果信息依然完整,就说明合格。
二、给状态加图标和文字标签。 成功 ✓ 已保存,错误 ✕ 手机号格式不正确,警告 ⚠ 余额不足。图标提供形状线索,文字提供语义线索,颜色只是锦上添花。表单校验必须有文字提示,红框是不够的。
三、用明度差而不是色相差。 前面说过三类色盲的明度感知都正常,所以只要两个颜色的相对亮度拉开足够距离,任何人都能区分。实操上,同一色相下取 300 和 700 两个色阶(如 #90CAF9 和 #1565C0),比取两个不同色相的同明度颜色安全得多。
四、避开红绿搭配,改用蓝橙。 数据可视化超过 3 个类别时直接用 Okabe-Ito 这类现成的色盲安全调色板;超过 8 个类别,颜色已不是好的区分手段,应改用形状、位置或直接标注文字。
五、提供高对比模式。 尊重系统的 prefers-contrast: more 和 prefers-color-scheme 媒体查询,允许用户在设置里切换。同时别把 outline: none 无脑加在全局样式里——键盘焦点环是无障碍的关键设施,去掉了就得用 :focus-visible 提供等价替代。
六、测试你的配色,别凭感觉。 完整的检查流程是三步:先用对比度检测工具确认所有文字都过 AA 4.5:1,再用色盲模拟器看三类色觉下的效果,最后把界面转灰度看信息是否还完整。选主色阶时用取色器在 HSL 空间调整明度而不是随手改 HEX,能让整套色板的明度关系更可控。
总结
色觉异常影响约 8% 的男性和 0.5% 的女性,其中绿色弱最常见(男性约 5%)。三类色盲的共同点是明度感知正常,这是所有无障碍配色技巧的立足点——能用明度差解决的,就不要依赖色相差。
WCAG 对比度的算法是先把 sRGB 线性化,再按 0.2126R + 0.7152G + 0.0722B 算相对亮度,最后取 (L亮+0.05)/(L暗+0.05)。AA 级正文要 4.5:1,大字 3:1;AAA 级正文 7:1。 记住几个数:#767676 灰在白底上是 4.54:1(刚好达标),#999999 只有 2.85:1(不合规),纯绿 #00FF00 仅 1.37:1,Bootstrap 的成功绿 #28A745 是 3.13:1(作正文色不达标)。
「红错绿对」的问题不在于用了红和绿,而在于颜色成了唯一的信息载体。补上图标和文字后,颜色退化成冗余强化信号,问题就消失了,改造成本几乎为零。
配色选择上,蓝—橙是三类色觉都能区分的黄金组合,深浅同色相的大明度差同样安全,红—绿、绿—棕、黄—亮绿则要坚决避开。最后别忘了那个五秒钟的自检动作:把界面截图转成灰度,看信息是否还完整。 这一步能筛掉八成的无障碍问题。