같은 명도, 다른 상대 휘도

Moyoutil 색상 변환기에 #FF0000과 #00FF00을 입력하면 각각 hsl(0, 100%, 50%)와 hsl(120, 100%, 50%)가 나옵니다. 두 색의 HSL 명도는 50%이지만 WCAG의 sRGB 상대 휘도는 각각 0.2126과 0.7152입니다. HSL 명도와 상대 휘도는 서로 다른 양입니다. CSS Color 4도 HSL 명도가 시각적으로 균일한 척도가 아니라고 설명합니다.

명도가 모두 50%인 빨강과 초록의 상대 휘도 및 흰색 대비 비율 비교
직접 제작한 계산 비교도. Y는 WCAG 상대 휘도, 아래 비율은 #FFFFFF와의 대비입니다. 색만으로 구별하지 않고 코드와 숫자도 표시했습니다.

W3C CSS Color 4 §7: HSL

RGB 채널을 그대로 평균 내면 안 됩니다

WCAG 계산은 0~255 채널을 255로 나눈 뒤 선형화하고, R·G·B에 0.2126·0.7152·0.0722의 가중치를 적용합니다. 대비 비율은 더 밝은 색과 더 어두운 색의 상대 휘도를 사용한 (L1 + 0.05) / (L2 + 0.05)입니다. 흰색과의 비율은 빨강 약 3.9985:1, 초록 약 1.3722:1입니다. 표시값은 소수 네 자리로 반올림했으며 적합성 판단에 반올림값을 사용하면 안 됩니다.

아래 코드는 계산을 재현하는 별도 예시입니다. Moyoutil 색상 도구는 HEX·RGB·HSL 변환을 제공하며 대비 비율이나 WCAG 적합성을 표시하지 않습니다. 실제 작업에서는 글자색과 배경색을 함께 검사하세요. 투명도·이미지·그라데이션이 있는 배경은 이 불투명 단색 예시의 적용 범위 밖입니다.

const linear = n => {
  const s = n / 255;
  return s <= 0.04045 ? s / 12.92
    : ((s + 0.055) / 1.055) ** 2.4;
};
const luminance = rgb => {
  const [r, g, b] = rgb.map(linear);
  return 0.2126*r + 0.7152*g + 0.0722*b;
};
const contrast = (a, b) => {
  const x = luminance(a), y = luminance(b);
  return (Math.max(x,y)+0.05)
       / (Math.min(x,y)+0.05);
};
console.log(contrast([255,0,0], [255,255,255]).toFixed(4));
console.log(contrast([0,255,0], [255,255,255]).toFixed(4));
// 3.9985
// 1.3722

W3C WCAG 2.2: relative luminance and contrast ratio

자주 묻는 질문

대비 비율 하나면 접근성이 모두 확인되나요?

아닙니다. 이 글은 두 불투명 색의 대비 계산만 다룹니다. 텍스트 크기와 사용 맥락에 따른 기준 및 다른 접근성 요구사항은 별도로 확인해야 합니다.