色彩对比度
色彩对比度是确保网页文本可读性的核心要素之一。对于视力不佳、色盲或在强光环境下使用设备的用户来说,足够的文字与背景对比度是阅读内容的前提。本节将详细介绍 WCAG AA 和 AAA 级别的对比度标准、对比度计算方法、常用检测工具,以及开发中常见的对比度错误和修复方案。
前置知识
阅读本节前,建议先了解:屏幕阅读器兼容
对比度标准
WCAG 定义了不同合规级别的最小对比度要求:
文本对比度要求
| 级别 | 普通文本(< 18pt / < 14pt 加粗) | 大号文本(>= 18pt / >= 14pt 加粗) |
|---|---|---|
| AA | 4.5 : 1 | 3 : 1 |
| AAA | 7 : 1 | 4.5 : 1 |
非文本元素(图标、边框等)
| 级别 | 最低对比度 |
|---|---|
| AA | 3 : 1 |
大号文本定义
- 18pt(24px):普通文本
- 14pt(18.66px):加粗文本
- 或等效大小的字号(可通过
rem/em缩放)
对比度计算
相对亮度公式
WCAG 使用以下公式计算颜色的相对亮度:
L = 0.2126 * R + 0.7152 * G + 0.0722 * B
其中:
- R、G、B 的值需要先转换为 sRGB 色彩空间中的线性值
- 如果 sRGB 值 <= 0.03928:线性值 = sRGB / 12.92
- 如果 sRGB 值 > 0.03928:线性值 = ((sRGB + 0.055) / 1.055) ^ 2.4对比度比率
对比度比率 = (L1 + 0.05) / (L2 + 0.05)
其中 L1 是较亮颜色的相对亮度,L2 是较暗颜色的相对亮度常见颜色组合对比度
| 前景色 | 背景色 | 对比度比率 | WCAG AA | WCAG AAA |
|---|---|---|---|---|
#000000(黑) | #FFFFFF(白) | 21:1 | 通过 | 通过 |
#333333 | #FFFFFF | 12.6:1 | 通过 | 通过 |
#666666 | #FFFFFF | 5.7:1 | 通过 | 未通过 |
#999999 | #FFFFFF | 2.8:1 | 未通过 | 未通过 |
#FFFFFF(白) | #0066cc(蓝) | 4.6:1 | 通过 | 未通过 |
#FFFFFF(白) | #004499(深蓝) | 7.3:1 | 通过 | 通过 |
#FFFF00(黄) | #FFFFFF(白) | 1.1:1 | 未通过 | 未通过 |
常见错误与修复
错误 1:灰色文字在白色背景上
html
<!-- 错误:对比度不足 -->
<p style="color: #999999; background: #ffffff;">
这段文字对比度不足,WCAG AA 未通过
</p>
<!-- 修复:加深文字颜色 -->
<p style="color: #595959; background: #ffffff;">
加深后的文字颜色,WCAG AA 通过(5.9:1)
</p>
<!-- 更好:使用更深的灰色 -->
<p style="color: #4a4a4a; background: #ffffff;">
更深的灰色,对比度更佳(7.2:1),WCAG AAA 通过
</p>错误 2:链接颜色与正文颜色对比度不足
html
<!-- 错误:浅蓝色链接在白色背景上 -->
<a href="#" style="color: #88aacc; background: white;">点击这里</a>
<!-- 对比度:约 2.5:1,未通过 -->
<!-- 修复:使用足够深的链接颜色 -->
<a href="#" style="color: #0066cc; background: white;">查看详情</a>
<!-- 对比度:4.6:1,通过 AA -->错误 3:占位符文本对比度不足
html
<!-- 错误:占位符颜色太浅 -->
<input style="color: #333; background: #fff;"
placeholder="请输入用户名" />
<!-- 占位符默认灰色(#999)对比度不足 -->
<!-- 修复:确保占位符颜色足够深 -->
<style>
input::placeholder {
color: #595959; /* 对比度 5.9:1,通过 AA */
}
</style>错误 4:图标对比度不足
html
<!-- 错误:浅色图标在浅色背景上 -->
<svg style="color: #cccccc;">
<path d="..." fill="currentColor" />
</svg>
<!-- 对比度:1.6:1,未通过 -->
<!-- 修复:加深图标颜色 -->
<svg style="color: #595959;">
<path d="..." fill="currentColor" />
</svg>
<!-- 对比度:5.9:1,通过 AA -->检测工具
在线工具
| 工具 | 地址 | 说明 |
|---|---|---|
| WebAIM Contrast Checker | webaim.org/resources/contrastchecker/ | 最常用的在线对比度检查器 |
| Colour Contrast Analyser | apps.microsoft.com | 桌面应用,Windows/Mac |
| Accessible Colors | accessible-colors.com | 生成满足 WCAG 的调色板 |
| Contrast Ratio | contrast-ratio.com | 快速在线对比度检查 |
浏览器扩展
- axe DevTools:Chrome 扩展,包含对比度检查
- Lighthouse:Chrome 内置,审计无障碍问题时会检查对比度
- Colour Contrast Analyzer:Chrome/Firefox 扩展
CSS 中的工具
css
/* 使用 CSS 变量确保对比度 */
:root {
--text-primary: #1a1a2e; /* 深色主文本 */
--text-secondary: #4a4a4a; /* 深色次文本 */
--text-muted: #595959; /* 辅助文本 */
--bg-primary: #ffffff; /* 白色背景 */
--bg-secondary: #f5f5f5; /* 浅灰背景 */
}
body {
color: var(--text-primary); /* 对比度 ~16:1 */
background: var(--bg-primary);
}
.text-muted {
color: var(--text-muted); /* 对比度 ~7:1 */
}不依赖颜色传达信息
WCAG 不仅要求足够的对比度,还要求信息不能仅通过颜色传达:
html
<!-- 错误:仅用红色标记错误 -->
<p style="color: red;">此字段必填</p>
<!-- 错误:仅用颜色区分链接 -->
<p><a style="color: blue;">普通链接</a></p>
<p><a style="color: blue; text-decoration: none;">无下划线链接</a></p>
<!-- 正确:同时使用文字和图标 -->
<p><span aria-hidden="true">⚠</span> 错误:此字段为必填项</p>
<!-- 正确:链接有下划线 -->
<a href="#" style="color: #0066cc; text-decoration: underline;">
点击查看
</a>实战示例:高对比度页面
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>高对比度页面示例</title>
<style>
/* CSS 变量定义高对比度颜色 */
:root {
--bg: #ffffff;
--text: #1a1a2e;
--text-secondary: #4a4a4a;
--accent: #0066cc;
--accent-hover: #004499;
--error: #b71c1c;
--success: #2e7d32;
--border: #ccc;
--placeholder: #595959;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
color: var(--text);
background: var(--bg);
line-height: 1.6;
}
/* 链接:下划线 + 颜色 */
a {
color: var(--accent);
text-decoration: underline;
}
a:hover {
color: var(--accent-hover);
}
a:focus-visible {
outline: 3px solid #ff6600;
outline-offset: 2px;
}
/* 按钮:对比度 >= 4.5:1 */
.btn-primary {
background: var(--accent);
color: #ffffff;
padding: 0.5rem 1.5rem;
border: 2px solid var(--accent);
border-radius: 4px;
cursor: pointer;
font-weight: 600;
}
.btn-secondary {
background: transparent;
color: var(--accent);
padding: 0.5rem 1.5rem;
border: 2px solid var(--accent);
border-radius: 4px;
cursor: pointer;
font-weight: 600;
}
/* 表单:确保标签和输入框对比度 */
label {
display: block;
margin-bottom: 0.25rem;
font-weight: 600;
color: var(--text);
}
input {
padding: 0.5rem;
border: 2px solid var(--border);
border-radius: 4px;
font-size: 1rem;
color: var(--text);
background: var(--bg);
}
input:focus {
border-color: var(--accent);
outline: 3px solid rgba(0, 102, 204, 0.3);
}
/* 占位符对比度 */
input::placeholder {
color: var(--placeholder); /* 对比度 ~5.9:1 */
}
/* 错误消息:红色 + 图标 + 文字 -->
.error-message {
color: var(--error);
font-size: 0.875rem;
margin-top: 0.25rem;
}
/* 状态标签:同时使用颜色和文字/图标 */
.status-badge {
display: inline-flex;
align-items: center;
gap: 0.25rem;
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 600;
}
.status-badge.success {
background: #e8f5e9;
color: var(--success);
}
.status-badge.error {
background: #ffebee;
color: var(--error);
}
/* 图标确保 3:1 对比度 */
.icon {
width: 24px;
height: 24px;
color: var(--text-secondary); /* 对比度 > 7:1 */
}
</style>
</head>
<body>
<h1>高对比度页面</h1>
<p>
本页面所有文本满足 <strong>WCAG AA</strong> 对比度标准。
链接有下划线,错误消息同时使用颜色和文字标记。
</p>
<form>
<label for="name">姓名</label>
<input type="text" id="name" placeholder="请输入姓名" />
<label for="email">电子邮箱</label>
<input type="email" id="email" placeholder="example@email.com" />
<span class="error-message" role="alert">请输入有效的邮箱地址</span>
<button type="submit" class="btn-primary">提交</button>
<button type="button" class="btn-secondary">取消</button>
</form>
<p>
<span class="status-badge success">
<span aria-hidden="true">✓</span> 已完成
</span>
<span class="status-badge error">
<span aria-hidden="true">✗</span> 未通过
</span>
</p>
</body>
</html>注意事项
- 大号文本标准不同:18pt 以上或 14pt 加粗的文本只需 3:1 对比度
- 不要用纯黑 #000 和纯白 #FFF:过于强烈的对比也可能造成不适,可考虑深灰配白色
- 占位符不是标签:placeholder 的对比度同样需要达标
- 图标需要对比度:功能性的图标(非装饰性)需要至少 3:1 对比度
- 考虑色盲用户:选择颜色时避免仅依赖红/绿色传达信息
最佳实践
- 在设计阶段使用对比度检查工具验证所有颜色组合
- 使用 CSS 变量统一管理颜色,确保一致性
- 所有文本至少达到 WCAG AA 标准(4.5:1)
- 链接使用下划线,不要仅依赖颜色区分
- 错误和警告同时使用颜色 + 文字/图标
- 使用 Lighthouse 或 axe-core 定期审计对比度
- 为高对比度模式提供备选样式表
下一节
继续学习:文字缩放与适配