← 返回博客首页

开发者色彩指南:HEX/RGB/HSL、无障碍对比度与配色方案生成

为什么开发者需要懂色彩理论?

色彩不仅仅是设计师的领域。作为开发者,理解色彩模型、对比度和无障碍标准,能帮助你:

  • 正确实现设计稿,避免颜色失真
  • 构建符合 WCAG 无障碍标准的界面
  • 编写动态配色和主题切换逻辑
  • 在没有设计师时做出合理的配色决策

颜色模型详解

HEX(十六进制)

Web 中最常用的颜色表示法,格式为 #RRGGBB,每两位表示一个通道的十六进制值(00-FF)。

#FF0000  -> 纯红
#00FF00  -> 纯绿
#0000FF  -> 纯蓝
#FFFFFF  -> 白色
#000000  -> 黑色

8 位 HEX 包含 Alpha 通道:#RRGGBBAA,如 #FF000080 表示半透明红色。

RGB / RGBA

加色模型,通过红、绿、蓝三个通道(0-255)混合表示颜色。

color: rgb(255, 0, 0);        /* 纯红 */
color: rgba(255, 0, 0, 0.5);  /* 半透明红 */

现代 CSS 也支持空格语法:

color: rgb(255 0 0);
color: rgb(255 0 0 / 50%);

HSL / HSLA

HSL 更符合人类对颜色的直觉理解,三个分量分别为:

  • H(Hue 色相):0-360 度,色轮上的角度
  • S(Saturation 饱和度):0-100%,颜色的鲜艳程度
  • L(Lightness 亮度):0-100%,0 为全黑,100 为全白
color: hsl(0, 100%, 50%);    /* 纯红 */
color: hsl(120, 100%, 50%);  /* 纯绿 */
color: hsl(240, 100%, 50%);  /* 纯蓝 */

色相参考

角度 颜色
红色
30° 橙色
60° 黄色
120° 绿色
180° 青色
240° 蓝色
270° 紫色
360° 红色

模型转换

HEX → RGB

function hexToRgb(hex) {
  const r = parseInt(hex.slice(1, 3), 16);
  const g = parseInt(hex.slice(3, 5), 16);
  const b = parseInt(hex.slice(5, 7), 16);
  return { r, g, b };
}

RGB → HSL

function rgbToHsl(r, g, b) {
  r /= 255; g /= 255; b /= 255;
  const max = Math.max(r, g, b);
  const min = Math.min(r, g, b);
  let h, s, l = (max + min) / 2;

  if (max === min) {
    h = s = 0; // 灰度
  } else {
    const d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    switch (max) {
      case r: h = (g - b) / d + (g < b ? 6 : 0); break;
      case g: h = (b - r) / d + 2; break;
      case b: h = (r - g) / d + 4; break;
    }
    h /= 6;
  }
  return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100) };
}

无障碍与对比度

WCAG 对比度标准

Web 内容无障碍指南(WCAG)定义了文本与背景之间的最低对比度要求:

等级 正常文本 大号文本(18pt+ 或 14pt 粗体)
AA(最低要求) 4.5:1 3:1
AAA(增强) 7:1 4.5:1

对比度计算

对比度基于相对亮度(Relative Luminance)计算:

function getLuminance(r, g, b) {
  const [rs, gs, bs] = [r, g, b].map(c => {
    c /= 255;
    return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
  });
  return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
}

function getContrastRatio(rgb1, rgb2) {
  const l1 = getLuminance(...rgb1);
  const l2 = getLuminance(...rgb2);
  const [lighter, darker] = l1 > l2 ? [l1, l2] : [l2, l1];
  return (lighter + 0.05) / (darker + 0.05);
}

// 示例:黑底白字对比度为 21:1(最高)
getContrastRatio([0, 0, 0], [255, 255, 255]); // 21

常见对比度问题

  • 浅灰色文字在白色背景上往往不达标(如 #999 on #FFF 对比度仅 2.85:1)
  • 品牌色作为按钮文字时需验证对比度
  • 深色模式下同样需要检查对比度

配色方案生成

经典配色方法

1. 互补色(Complementary)

色轮上相对的两种颜色(相差 180°),对比强烈:

基础色: HSL(210, 70%, 50%)  -> 蓝色
互补色: HSL(30, 70%, 50%)   -> 橙色

2. 类似色(Analogous)

色轮上相邻的颜色(相差 30°-60°),和谐统一:

HSL(180, 70%, 50%)  -> 青色
HSL(210, 70%, 50%)  -> 蓝色
HSL(240, 70%, 50%)  -> 蓝紫色

3. 三元色(Triadic)

色轮上等距的三种颜色(相差 120°),活泼平衡:

HSL(0, 70%, 50%)    -> 红色
HSL(120, 70%, 50%)  -> 绿色
HSL(240, 70%, 50%)  -> 蓝色

4. 单色方案(Monochromatic)

同一色相,通过调整饱和度和亮度生成层次:

function generateMonochromatic(baseHue) {
  return [
    `hsl(${baseHue}, 80%, 90%)`,  // 最浅
    `hsl(${baseHue}, 70%, 70%)`,
    `hsl(${baseHue}, 80%, 50%)`,  // 基准
    `hsl(${baseHue}, 70%, 30%)`,
    `hsl(${baseHue}, 60%, 15%)`   // 最深
  ];
}

使用 HSL 生成配色方案

HSL 是程序化生成配色的最佳模型,因为只需调整色相角度即可得到和谐的颜色组合:

function generatePalette(baseHue, scheme = 'analogous') {
  const schemes = {
    complementary: [0, 180],
    analogous: [-30, 0, 30],
    triadic: [0, 120, 240],
    tetradic: [0, 90, 180, 270]
  };
  const offsets = schemes[scheme] || schemes.analogous;
  return offsets.map(offset =>
    `hsl(${(baseHue + offset + 360) % 360}, 65%, 55%)`
  );
}

Tailwind / Design Token 实践

现代设计系统使用 CSS 变量定义颜色阶梯:

:root {
  --primary-50:  #eff6ff;
  --primary-100: #dbeafe;
  --primary-500: #3b82f6;
  --primary-700: #1d4ed8;
  --primary-900: #1e3a8a;
}

生成工具如 Tailwind CSS Color Generator 可以从单一 HEX 值生成完整阶梯。

CSS 颜色函数进阶

color-mix() 混合颜色

/* 混合 50% 红色和 50% 蓝色 */
.result { background: color-mix(in srgb, red 50%, blue 50%); }

color() 函数访问不同色彩空间

/* Display P3 广色域 */
.vivid { color: color(display-p3 1 0 0); }

/* 相对颜色:基于已有颜色派生 */
.darker { color: hsl(from var(--base) h s calc(l - 10%)); }

prefers-color-scheme 深色模式

:root { --bg: #ffffff; --text: #1a1a1a; }

@media (prefers-color-scheme: dark) {
  :root { --bg: #1a1a1a; --text: #ffffff; }
}

body { background: var(--bg); color: var(--text); }

工具与资源

工具 用途
Coolors 配色方案生成
Adobe Color 色轮与配色规则
WebAIM Contrast Checker 对比度检测
Contrast Ratio 简洁对比度工具
OKLCH Picker OKLCH 色彩空间选择器
← 返回博客首页