Skip to content

色彩对比度

色彩对比度是确保网页文本可读性的核心要素之一。对于视力不佳、色盲或在强光环境下使用设备的用户来说,足够的文字与背景对比度是阅读内容的前提。本节将详细介绍 WCAG AA 和 AAA 级别的对比度标准、对比度计算方法、常用检测工具,以及开发中常见的对比度错误和修复方案。

前置知识

阅读本节前,建议先了解:屏幕阅读器兼容

对比度标准

WCAG 定义了不同合规级别的最小对比度要求:

文本对比度要求

级别普通文本(< 18pt / < 14pt 加粗)大号文本(>= 18pt / >= 14pt 加粗)
AA4.5 : 13 : 1
AAA7 : 14.5 : 1

非文本元素(图标、边框等)

级别最低对比度
AA3 : 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 AAWCAG AAA
#000000(黑)#FFFFFF(白)21:1通过通过
#333333#FFFFFF12.6:1通过通过
#666666#FFFFFF5.7:1通过未通过
#999999#FFFFFF2.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 Checkerwebaim.org/resources/contrastchecker/最常用的在线对比度检查器
Colour Contrast Analyserapps.microsoft.com桌面应用,Windows/Mac
Accessible Colorsaccessible-colors.com生成满足 WCAG 的调色板
Contrast Ratiocontrast-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>

注意事项

  1. 大号文本标准不同:18pt 以上或 14pt 加粗的文本只需 3:1 对比度
  2. 不要用纯黑 #000 和纯白 #FFF:过于强烈的对比也可能造成不适,可考虑深灰配白色
  3. 占位符不是标签:placeholder 的对比度同样需要达标
  4. 图标需要对比度:功能性的图标(非装饰性)需要至少 3:1 对比度
  5. 考虑色盲用户:选择颜色时避免仅依赖红/绿色传达信息

最佳实践

  • 在设计阶段使用对比度检查工具验证所有颜色组合
  • 使用 CSS 变量统一管理颜色,确保一致性
  • 所有文本至少达到 WCAG AA 标准(4.5:1)
  • 链接使用下划线,不要仅依赖颜色区分
  • 错误和警告同时使用颜色 + 文字/图标
  • 使用 Lighthouse 或 axe-core 定期审计对比度
  • 为高对比度模式提供备选样式表

下一节

继续学习:文字缩放与适配

参考链接