Skip to content
블로그로 돌아가기
튜토리얼

WCAG 웹 색상 대비 완전 가이드: AA, AAA와 APCA 알고리즘 정리

WCAG 색상 대비 가이드: 4.5:1 AA와 7:1 AAA 기준, APCA Lc 알고리즘, 색맹 대응, 그리고 실패하는 색 조합을 고치는 방법까지 한 번에 정리.

15 분 소요

WCAG 색상 대비 비율: AA, AAA & APCA — 2026 가이드

버튼 하나를 배포합니다. 브랜드 오렌지에 흰색 글자, 4K 모니터에서는 선명해 보입니다. 그런데 접근성 감사 결과가 빨간불로 돌아옵니다. WCAG 대비 비율이 1.97:1, 본문 텍스트 AA 기준인 4.5:1에 한참 못 미칩니다. 본인 눈에는 멀쩡해 보이던 버튼이, 전 세계 약 2억 2천만 명의 저시력 사용자에게는 읽히지 않습니다. 이 가이드는 그 문제를 해결하는 데 필요한 숫자를 다룹니다. WCAG 2 대비 비율, AAA 등급, 새 APCA Lc 알고리즘, 여덟 가지 색각이상 분류, 빌드에 넣을 수 있는 JavaScript 구현입니다.

빠른 참조: WCAG와 APCA 기준 한눈에 보기

표준본문 텍스트큰 글자UI / 아이콘비고
WCAG AA≥ 4.5:1≥ 3:1≥ 3:1법적 최저선
WCAG AAA≥ 7:1≥ 4.5:1≥ 3:1강화 목표
APCA 본문Lc 75+Lc 60+Lc 45+ (아이콘)초안, 지각 기반

“큰 글자”란 18pt 이상의 일반 굵기 또는 14pt 이상의 굵은 글자(CSS 기준 약 24px와 약 18.66px)를 뜻합니다. “UI”는 폼 테두리, 포커스 링, 그리고 사용자가 페이지를 조작하기 위해 반드시 인지해야 하는 그래픽 요소를 모두 포함합니다. 로고와 순수한 장식용 그래픽은 대비 요구 사항에서 제외됩니다.

WCAG 색상 대비란 무엇인가

WCAG 대비 비율이란 텍스트와 배경의 상대 휘도를 비교해 1:1(대비 없음)부터 21:1(최대)까지 매기는 수치 지표입니다. 웹 콘텐츠 접근성 지침(Web Content Accessibility Guidelines)은 본문 텍스트에 대해 ≥ 4.5:1(AA)을 요구하며, 강화 준수를 위해서는 ≥ 7:1(AAA)을 요구합니다.

이 단일 비율이 전 세계 대부분의 접근성 감사를 좌우합니다. W3C는 2008년 WCAG 2.0에서 이를 처음 발표했고, 2.1(2018)과 2.2(2023)에서 다듬었으며, 현재 주요 규제 기관은 모두 이 기준을 가리킵니다. 미국의 ADA, 2025년 6월부터 시행된 유럽 접근성법(European Accessibility Act), 미국 연방 기관을 대상으로 하는 Section 508, 캐나다의 AODA는 모두 WCAG 2.x AA를 사실상의 하한선으로 사용합니다.

법 이야기는 잠시 접고, 이게 왜 중요한지 봅니다. 전 세계 약 2억 2천만 명이 시각 장애인은 아니지만 저시력 상태입니다. 이들은 화면을 읽을 수 있지만, 글자와 배경의 대비가 충분히 높을 때만 그렇습니다. 남성의 약 8%, 여성의 약 0.5%가 색각이상을 가지고 있습니다. 나이가 들면 수정체가 황변하고 동공 개구가 줄어들어, 60세 이후 체감 대비가 2030% 떨어집니다. 야외에서 스마트폰을 쓰면 햇빛 반사 때문에 추가로 2040%가 소실됩니다. 책상에서 4.5:1을 받는 페이지는, 위의 모든 사용자가 그래도 읽을 수 있는 최저 한계선입니다.

가장 신경 써야 할 사람은 프로덕션 UI를 출시하는 프런트엔드 엔지니어, 브랜드 팔레트를 고르는 디자이너, 감사를 수행하는 접근성 전문가, 법적 노출을 책임지는 컴플라이언스 팀입니다. 수학 자체는 짧지만, 그 수학이 강요하는 의사 결정은 그렇지 않습니다.

WCAG 2.x 대비 비율: 수식과 기준

W3C는 대비를 세 단계로 짧게 정의합니다. WCAG 대비 비율을 계산하려면 (1) 각 색상을 감마 인코딩된 sRGB에서 선형 광 값으로 변환하고, (2) 인간 눈이 빨강·초록·파랑에 대해 가지는 민감도 계수를 적용해 상대 휘도를 계산한 뒤, (3) 두 휘도를 작은 상수 오프셋과 함께 나누어 거의 검정에 가까운 값을 처리합니다.

WCAG 2.1 §1.4.3에서 정의한 상대 휘도 공식은 다음과 같습니다.

L = 0.2126 × R_lin + 0.7152 × G_lin + 0.0722 × B_lin

R_lin, G_lin, B_lin은 sRGB 감마 곡선을 되돌린 선형 광 채널 값입니다. 초록에 0.7152라는 가중치가 붙는 것은 인간 눈의 초록 민감도가 매우 강하기 때문입니다. 같은 광 에너지당 초록은 파랑보다 시각적으로 약 7배 더 크게 느껴집니다.

비율 공식은 다음과 같습니다.

ratio = (L_lighter + 0.05) / (L_darker + 0.05)

+0.05는 순수한 검정(L = 0)에서 0으로 나누는 상황을 방지하면서, 순수한 흰색 위 순수한 검정에 대해 (1 + 0.05) / (0 + 0.05) = 21:1이라는 최댓값을 제공합니다. 최솟값은 동일한 두 색일 때 1:1입니다.

다음은 약 30줄짜리 순수 JavaScript 구현입니다. 의존성이 전혀 없어 어디서든 동작합니다.

// sRGB hex → 선형 광 채널
function srgbToLinear(channel8bit) {
  const v = channel8bit / 255;
  return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
}

// "#RRGGBB" → 상대 휘도 [0, 1]
function relativeLuminance(hex) {
  const h = hex.replace("#", "");
  const r = parseInt(h.slice(0, 2), 16);
  const g = parseInt(h.slice(2, 4), 16);
  const b = parseInt(h.slice(4, 6), 16);
  return (
    0.2126 * srgbToLinear(r) +
    0.7152 * srgbToLinear(g) +
    0.0722 * srgbToLinear(b)
  );
}

// 두 hex 색상 간의 WCAG 2.x 대비 비율
function contrastRatio(hexA, hexB) {
  const lA = relativeLuminance(hexA);
  const lB = relativeLuminance(hexB);
  const [lighter, darker] = lA > lB ? [lA, lB] : [lB, lA];
  return (lighter + 0.05) / (darker + 0.05);
}

// 예시: 흰색 위 다크 슬레이트 본문 텍스트
console.log(contrastRatio("#475569", "#ffffff").toFixed(2));
// → "7.58" — AA 4.5:1을 여유 있게 통과하고 AAA 7:1도 살짝 넘김

색상 변환기에 hex 코드 두 개를 넣으면 같은 숫자가 돌아오며, APCA Lc 값, 색역 분류, 8채널 CVD 미리보기도 함께 표시됩니다. 기준 자체는 명확합니다.

요소AA 최소AAA 최소비고
일반 본문 텍스트4.5:17:118pt 일반 / 14pt 굵은 글자 미만
큰 글자3:14.5:1≥ 18pt 일반 또는 ≥ 14pt 굵은 글자
UI 구성 요소 / 아이콘3:1WCAG 2.1 §1.4.11에서 2018년에 추가
로고 및 장식면제면제대비 요구 사항 없음

CSS 단위 환산에서 헷갈리는 부분이 있습니다. 브라우저 기본값에서 18pt = 24px, 14pt = 18.66px입니다. 현대적 기본값인 16px 본문 폰트는 “큰 글자” 문턱 아래에 있으므로 더 엄격한 4.5:1 AA 규칙을 따릅니다. font-weight: 700인 20px 제목은 큰 글자에 해당하여 더 느슨한 3:1 기준을 적용받습니다.

팀에서 자주 놓치는 미묘한 지점이 하나 있습니다. WCAG의 “큰 글자” 면제는 시각적 크기에 따른 가독성 문제이지 제목 시맨틱과는 무관합니다. 14px짜리 <h2>큰 글자가 아닙니다. 여전히 4.5:1이 필요합니다. 24px짜리 마케팅 문구 단락은 큰 글자에 해당하여 3:1 하한선을 따릅니다. 규칙은 렌더링된 픽셀 크기와 굵기에만 의존하고, 태그 이름에는 의존하지 않습니다. 감사자는 이 불일치를 잡아낼 것이며, 진실의 원천은 HTML 시맨틱이 아니라 CSS입니다.

비율 공식의 +0.05 상수에는 구체적인 유래가 있습니다. 이는 플레어(flare) 항을 나타내며, 화면 표면에서 반사되는 주변광이 순수한 검정의 외견상 휘도를 최소 바닥값까지 끌어올린다는 사실을 반영합니다. 이게 없다면 순수한 흰색 위에 진짜 검정을 표시하는 OLED 픽셀은 0으로 나누는 결과를 낳을 것입니다. 이를 포함하면 달성 가능한 최대 비율은 21:1이 됩니다. 모든 접근성 도구가 강조하는 그 숫자입니다. 플레어를 감안하면 21:1을 넘는 물리적 화면은 존재하지 않으며, 그래서 WCAG 척도가 그 지점에서 멈춰 있는 것입니다.

AA 대 AAA: 어느 등급을 목표로 잡아야 할까

AA는 법적 최저선이고, AAA는 지향 등급입니다. 상업 사이트 대부분은 AA를 목표로 합니다. AAA를 통과하려면 브랜드 색상을 회색조 쪽으로 끌고 가야 하는데, 마케팅 팀 대부분이 이를 거부하기 때문입니다. 의사 결정은 “더 높은 게 더 좋다”가 아니라 사용자 도달 범위와 브랜드 표현 사이의 절충안입니다.

상황권장 등급이유
일반 상업 사이트AAADA / EAA 준수 기준선; 법원은 WCAG 2 AA를 인용
정부 / 공공 서비스AAASection 508 및 EU 법령은 AAA 권장
의료 / 교육AAA사용자 기반이 더 높은 접근성 요구로 기울어 있음
내부 대시보드AA청중이 알려져 있고, ROI 절충이 수용 가능
마케팅 랜딩 페이지AA + 브랜드 예외히어로 / CTA에는 브랜드 색 허용, 본문은 여전히 AA

AAA의 숨겨진 비용은 채도 높은 브랜드 오렌지를 흰색 배경에서 7:1로 통과시키려 할 때 처음 드러납니다. 통과가 안 됩니다. 오렌지가 더 이상 본인 브랜드가 아닐 때까지 어둡게 만들거나, AA를 받아들이고 그 오렌지를 어두운 배경 위에서 사용해 AAA를 넘기게 해야 합니다. 접근성을 적극적으로 신경 쓰는 회사를 포함해 많은 회사가 본문 콘텐츠에는 AA만 목표로 하고, 오류 메시지나 법적 고지처럼 중요한 텍스트에서만 AAA를 추구합니다.

규제 당국은 AAA가 확산되기를 기다리지 않았습니다. 2024년 ADA의 웹 접근성 규정은 WCAG 2.1 AA를 인용합니다. 2025년 6월부터 시행 중인 유럽 접근성법은 적용 대상 디지털 서비스 전반에서 WCAG 2.1 AA를 요구합니다. 미국 연방 정부의 Section 508은 WCAG 2.0 AA를 기준선으로 사용합니다(가능한 곳에서는 AAA를 권장). 캐나다의 AODA, 그리고 온타리오의 접근성 법령도 WCAG 2.0 AA를 가리킵니다. 패턴은 일관적입니다. AA는 통과선, AAA는 목표입니다.

APCA: 새로운 지각 기반 알고리즘

APCA(Advanced Perceptual Contrast Algorithm)는 Myndex 브랜드 아래에서 Andrew Somers가 설계했으며, WCAG 3의 후보 알고리즘입니다. WCAG 2의 대칭 비율을 -108에서 +108까지의 극성 부호 Lc 점수로 대체합니다. 부호는 대비가 어느 방향으로 흐르는지(밝은 배경 위 어두운 글자 vs 어두운 배경 위 밝은 글자)를 알려 주고, 크기는 실제 발광 디스플레이에서의 지각 대비를 반영합니다.

APCA가 중요한 이유는 WCAG 2의 대칭 공식이 실세계의 두 가지 효과를 놓치기 때문입니다.

  • 극성 비대칭. 어두운 배경 위 밝은 글자는 밝은 배경 위 어두운 글자와 동일한 WCAG 비율이라도 다르게 읽힙니다. WCAG 2는 양쪽 방향에 같은 숫자를 반환하지만, APCA는 그렇지 않습니다.
  • 디스플레이 모델링. WCAG 2 공식은 인쇄용 종이의 휘도 모델에서 도출되었습니다. APCA는 전형적인 사무실 조명 환경의 sRGB 디스플레이에 맞춰 튜닝되었으며, 이는 실제 사용자가 보는 환경에 훨씬 가깝습니다.

절충점도 있습니다. APCA는 더 복잡하고(극성 인지 지수와 폰트 굵기 보정이 들어갑니다), 아직 규제 표준이 아닙니다. Adrian Roselli의 2026년 4월 분석이 APCA의 현 위치를 가장 명료하게 요약합니다. 기술적으로는 유망하지만, WCAG 3 자체가 여전히 초기 초안 단계의 Silver 트랙 개발 중이고, APCA는 공식 알고리즘으로 비준되지 않았습니다.

APCA의 Bronze 수준 기준(대부분의 팀이 목표로 하는 실질적 하한선)은 다음과 같습니다.

용도권장 Lc최소 Lc
본문 텍스트 (16px, 굵기 400)90+75
큰 글자 (24px, 굵기 400)75+60
UI 요소 및 비텍스트 아이콘60+45
스폿 텍스트 / 플레이스홀더30+30

APCA가 흥미로운 이유는, 그리고 색상 변환기가 두 지표를 나란히 표시하는 이유는 WCAG 2와 결론이 갈리는 사례들 때문입니다.

  • 흰색(#FFFFFF) 위 오렌지(#FFA500): WCAG 2는 1.97:1을 반환하고, AA에서 명확한 실패입니다. APCA도 같은 결론으로 Lc 38 부근을 매겨 실패 판정을 내립니다. 두 알고리즘 모두 안 된다고 말하는데도, “보기엔 괜찮다”라며 이 조합을 그대로 출시하는 디자이너를 자주 봅니다.
  • 흰색(#FFFFFF) 위 중간 회색(#767676): WCAG 2는 4.54:1을 반환합니다. AA 4.5:1을 살짝 넘긴 기술적 통과입니다. APCA는 이 쌍에 Lc 60 정도를 매기는데, 이는 본문 텍스트에 대한 APCA Bronze의 75 기준 아래입니다. WCAG는 통과하지만 APCA는 실패합니다. 사용자가 체감하는 경험은 APCA의 판정에 더 가깝습니다. 흰색 위 그 회색은 비율이 시사하는 것보다 본문 크기에서 읽기가 더 어렵습니다.
  • 검정(#000000) 위 Tailwind blue-500(#3b82f6): WCAG 2는 5.71:1을 반환하며 AA를 여유 있게 통과합니다. APCA는 Lc 65 부근을 매기는데, 이는 본문 텍스트 최소치 Lc 75 아래입니다. 어두운 배경 위 밝은 파란색 글자, 다크 모드에서 흔히 쓰이는 패턴이 바로 “WCAG는 통과, APCA는 경고”의 대표 사례입니다.

한쪽 편을 들 필요는 없습니다. 프로덕션 팀 대부분이 안착한 실용적 입장은 이렇습니다. 컴플라이언스 감사가 검사하는 기준이므로 WCAG 2 AA를 규제 기준선으로 유지하고, APCA를 “이게 정말 읽히는가?” 직감 점검으로 병행 실행합니다. 다크 모드 디자인과 채도 높은 브랜드 색상에서 특히 그렇게 합니다. 색상 변환기는 두 숫자를 한 줄에 함께 보여 주므로 도구 사이를 오가는 컨텍스트 전환이 필요 없습니다.

색각이상과 대비를 넘어서

대비 비율은 색상 접근성의 절반에 불과합니다. 남성의 약 8%, 여성의 약 0.5%는 교과서적 삼색형 색각자와 다르게 색을 봅니다. 그리고 가장 흔한 변이인 녹색약(deuteranomaly)은 우리가 성공/오류 상태에 어디서나 사용하는 빨강/초록 쌍의 한가운데에 자리합니다. WCAG 1.4.1(“색의 사용”)은 색이 정보의 유일한 전달자가 되는 것을 명시적으로 금지하며, 이 규칙이 존재하는 이유가 바로 이것입니다.

색각 차이의 전체 분류 체계는 세 그룹으로 나뉩니다. 이색형 색각(dichromacy, 원추세포 하나가 결손), 이상 삼색형 색각(anomalous trichromacy, 원추세포 하나가 이동), 그리고 드문 단색형 색각(monochromacy)입니다.

유형통속 명칭영향 채널유병률 (남 / 여)
Protanopia적색맹L 원추세포 결손1.0% / 0.01%
Deuteranopia녹색맹M 원추세포 결손1.1% / 0.01%
Tritanopia청색맹S 원추세포 결손0.003% / 0.003%
Protanomaly적색약L 원추세포 이동1.3% / 0.02%
Deuteranomaly녹색약M 원추세포 이동5.0% / 0.4%
Tritanomaly청색약S 원추세포 이동0.01% / 0.01%
Achromatopsia전색맹모든 원추세포 결손0.003% (매우 드묾)
Cone monochromacy부분 회색원추세포 하나만 작동0.001%

녹색약(deuteranomaly) 하나만 해도 남성의 5%, 즉 스무 명 중 한 명입니다. 이 인구 집단은 빨간 오류 표시와 초록 성공 표시를 거의 같은 올리브 갈색 색조로 봅니다. 해결책은 색 체계를 다시 설계하는 것이 아니라, 두 번째 채널을 추가하는 것입니다. 빨간 오류 아이콘이 ”×” 모양과 “오류”라는 단어와 짝지어 있으면 위 표의 모든 변이를 통과합니다. 맨 빨간 점만 있다면 그렇지 못합니다.

코드로 CVD를 시뮬레이션할 때는 두 가지 표준 행렬 집합을 사용합니다. 이색형 색각에는 Brettel–Viénot–Mollon(1997), 이상 삼색형 색각에는 Machado–Oliveira–Fernandes(2009)입니다. Brettel 방식은 사용자의 입력 색을 남아 있는 두 원추세포 반응이 펼치는 평면에 투영합니다. Machado는 원추세포 이동을 심각도로 매개변수화합니다. 둘 다 SVG 필터나 CSS 행렬로 구현할 수 있습니다. 색상 변환기는 여덟 가지 변이 전부를 원클릭 미리보기로 제공하므로, 페이지를 떠나지 않고 브랜드 색상을 스펙트럼 전반에 걸쳐 훑어볼 수 있습니다.

페이지에 붙여 ID로 참조하는 짧은 SVG 필터를 쓰면, 임시 테스트용으로 브라우저 안에서 적색맹 시뮬레이션을 돌릴 수 있습니다.

<svg style="display: none">
  <filter id="protanopia">
    <feColorMatrix type="matrix" values="
      0.567 0.433 0.000 0 0
      0.558 0.442 0.000 0 0
      0.000 0.242 0.758 0 0
      0.000 0.000 0.000 1 0"/>
  </filter>
</svg>

<style>
  .preview-protanopia { filter: url(#protanopia); }
</style>

페이지 래퍼에 .preview-protanopia를 적용하면 적색맹 사용자가 보는 화면이 나타납니다. 녹색맹과 청색맹 행렬도 같은 방식으로 반복할 수 있습니다(계수는 Brettel 논문에 문서화되어 있으며, 대부분의 CVD 시뮬레이터 라이브러리에 번들로 들어 있습니다). Chrome DevTools의 Rendering 패널에는 “Emulate vision deficiencies” 아래에 같은 시뮬레이터가 기본 내장되어 있습니다. 빠른 점검에는 유용하지만, CI에서 스크린숏을 캡처하기에는 덜 유용합니다.

시뮬레이션을 넘어선 더 깊은 규칙이 있습니다. 두 상태의 유일한 차이가 색이 되도록 두지 마세요. 아이콘은 모양으로 구분해야 합니다(× vs ). 상태는 텍스트 라벨로 구분해야 합니다(“오류” vs “성공”). 카테고리는 패턴으로 구분해야 합니다(채움 vs 빗금). 색은 다른 신호들 위에 곱해지는 증폭기이지, 대체재가 아닙니다.

대비 검사기는 못 잡지만 CVD 시뮬레이터가 잡아내는 실패 부류가 있습니다. 색조만으로 구분되는 파이 차트 구간, 국가에 색을 입힌 지도 범례, 초록/노랑/빨강 그라데이션에 의존하는 상태 알약. 이 모두는 배경 대비 WCAG 2를 통과하면서도 녹색맹 사용자가 서로를 비교해서 읽을 때는 식별이 안 될 수 있습니다. 규칙은 둘러싼 캔버스와의 가독성만이 아니라, 디자인 안에서 인접한 색끼리의 가독성을 점검하는 것입니다. 같은 명도의 slate-500 두 구간이 나란히 놓이면 색조 회전과 무관하게 구분이 안 됩니다. 인접 구역 사이에 휘도 단계를 두면 차트는 모든 CVD 변이를 통과합니다.

전색맹과 원추 단색형 색각은 드물지만 명시적으로 설계에 포함할 가치가 있습니다. 이들은 모든 색조 구분을 무너뜨리기 때문입니다. 전색맹 사용자는 휘도만 인지합니다. 색으로 코드화된 UI가 그들에게는 흑백 사진처럼 보입니다. 페이지 전체에 filter: grayscale(1)을 적용했을 때(DevTools에서 시도해 보세요) 디자인이 버틴다면, “색이 유일한 신호가 아니다” 규칙의 가장 엄격한 버전을 통과한 것입니다. 가장 저렴하게 돌릴 수 있는 접근성 테스트이며, 켜는 순간 놀랄 만큼 많은 실패가 드러납니다.

Tailwind와 Material 팔레트 감사하기

프런트엔드 작업 대부분은 사전 구축된 팔레트를 사용합니다. Tailwind v4, Material 3, Radix, 또는 shadcn입니다. 접근성 질문은 “이 램프의 어느 단계에서 텍스트가 읽히기 시작하는가?”로 바뀝니다. 그리고 그 답은 공식 문서가 인정하는 것보다 훨씬 경험칙에 가깝습니다.

Tailwind v4의 slate 램프를 순수한 흰색에 대비시키면 WCAG와 APCA 숫자는 다음과 같이 떨어집니다.

Tailwind 클래스근사 hex흰색 대비 WCAGAA 본문AAA 본문APCA Lc (근사)
slate-400#94a3b82.56:1~38 ✗
slate-500#64748b4.76:1~60 ✗ 본문
slate-600#4755697.58:1~78 ✓ 본문
slate-700#33415510.35:1~90 ✓ 본문

여기서 도출되는 실용적인 규칙은 다음과 같습니다.

  • 본문 텍스트는 slate-600 이상이 필요합니다. slate-500은 WCAG AA는 통과하지만 APCA의 본문 텍스트 기준은 통과하지 못합니다. 준수는 하지만 편안하지 않습니다. slate-600이 안전한 하한선입니다.
  • UI 라벨과 보조 텍스트는 slate-500을 쓸 수 있습니다. UI 구성 요소는 3:1만 필요하므로 slate-500의 4.76:1은 충분히 여유롭고, 텍스트가 보조 시각 맥락을 함께 전달하는 경우가 많습니다.
  • 플레이스홀더는 slate-400 이하의 더 옅은 색을 써야 합니다. 플레이스홀더 텍스트는 입력란 위에 항상 보이는 라벨을 유지하는 경우에만 WCAG 1.4.3에서 장식으로 면제됩니다. 라벨 자리에 플레이스홀더를 쓰는 인라인 패턴은 본문 텍스트 기준을 충족해야 합니다.
  • slate-100 / slate-200 위 순수한 검정은 잉크 낭비입니다. 17:1 이상이 됩니다. 가독성을 잃지 않으면서도 더 부드러운 느낌을 주려면 텍스트 색으로 slate-700 또는 slate-800을 고려하세요.

Material 3는 유사한 색조 팔레트 구조를 사용합니다. surface-container-high는 톤 92(매우 밝음) 근처에, on-surface는 톤 10(거의 검정) 근처에 위치합니다. 같은 계열의 on-surfacesurface-* 토큰 사이의 대비는 Material 사양이 AA 통과를 보장합니다. on-surface-variant(톤 30)와 surface-container(톤 94)를 점검 없이 짝지어 쓰지 마십시오. 실제로 출시까지 갔던 미스를 본 적이 있습니다.

이미 가지고 있는 팔레트가 대비를 통과하지 못한다면, OKLCH가 가장 깔끔한 수정 경로를 제공합니다. hex 코드를 손에 잡히는 대로 조정하는 대신, 색을 OKLCH로 변환하고 C(채도)와 H(색조)를 고정한 채 L(명도)을 낮춰 대비가 통과할 때까지 줄이세요. OKLCH의 L 채널은 진짜로 지각 기반이므로, 브랜드 인지도는 그대로 유지하면서 대비만 단단해집니다. HEX → OKLCH 도구가 이 변환을 한 단계로 처리해 주며, 자매 글 OKLCH 완전 해설이 그 수학을 깊이 있게 다룹니다.

다크 모드는 별도 단락을 받을 자격이 있습니다. WCAG 2의 대칭 비율은 정의상 라이트 모드와 다크 모드에서 같은 조합을 통과시킵니다. 극성 인지형인 APCA는 동일한 hex 쌍이 라이트 모드보다 다크 모드에서 더 읽기 어렵다고 자주 표시합니다. 같은 수치 비율이라도 어두운 배경 위 밝은 글자는 그 반대보다 지각 대비를 항상 일부 잃습니다. 눈이 적응하는 방식 때문에 생기는 알려진 효과입니다. 배포 전에 모든 다크 모드 쌍에 대해 APCA를 다시 실행하세요.

대비 검사기와 CI 워크플로

디자이너와 엔지니어는 각자 선호하는 검사기가 있습니다. 실용적인 질문은 어떤 도구 조합을 실제 워크플로에 꿰맞출 것인가입니다. 2026년 현재의 현황은 다음과 같습니다.

도구WCAG 2APCACVD 시뮬레이션팔레트 감사
WebAIM Contrast Checker
Adobe Color
Stark (Figma 플러그인)
Polypane (브라우저)
Chrome DevTools 색상 피커✓ (실험)
axe DevTools✓ (페이지 수준)
Go Tools 색상 변환기✓ (8 유형)✓ (틴트/셰이드)

실제 제품 압력을 견디는 워크플로는 다음과 같이 생겼습니다.

  1. Figma에서, 디자이너가 각 프레임에 Stark를 실행해 실패하는 쌍을 일찍 표면화합니다. 어떤 hex 코드든 코드베이스에 들어오기 전에 Stark가 명백한 위반자를 잡아냅니다.
  2. hex 코드 인수인계 시점에, 엔지니어가 값을 색상 변환기에 붙여 넣어 WCAG 비율 + APCA Lc + 색역 분류 + CVD 미리보기를 한 줄에 받습니다. 다크 모드 쌍이나 채도 높은 브랜드 색이라면, 이 이중 지표가 Stark가 놓칠 수 있는 “WCAG 통과, APCA 실패” 사례를 잡아냅니다.
  3. PR 시점에, axe-core/playwright가 빌드된 페이지를 스캔해 렌더링된 DOM 위 모든 대비 위반을 동적 상태까지 포함해 검출합니다. 정적 디자인 파일이 놓치는 포커스 링, 호버 상태, 비활성 어포던스도 여기서 잡힙니다.
  4. QA에서, Chrome DevTools의 Rendering 탭이 중요한 플로에 대해 적색맹/녹색맹/청색맹 스폿 체크를 시뮬레이션합니다. DevTools의 색상 피커도 어떤 요소든 호버하면 WCAG 비율을 즉석에서 표시합니다.

Pa11y, Lighthouse CI, 그리고 @axe-core/playwright는 모두 대비 단언을 더 광범위한 접근성 감사의 일부로 노출합니다. 오늘날 어느 것도 APCA를 확인하지 않고, 모두 WCAG 2를 확인합니다. 현실적인 절충안은 “CI에서는 WCAG 2 AA를 강제하고, 브랜드 색과 다크 모드에 대해 APCA Lc를 수동으로 점검한다”입니다.

규모가 큰 디자인 시스템 팀에서 빌려올 만한 패턴이 있습니다. 대비 검사를 페이지 수준 QA에만 두지 말고, 토큰 검증 단계에 구워 넣는 것입니다. 디자인 토큰이 소스 파일(JSON, YAML, 또는 TypeScript 모듈)에서 컴파일된다면, 시스템이 허용하는 모든 --text-* × --surface-* 짝을 열거하고 최소 WCAG 비율을 단언하는 스크립트를 추가하세요. 스크립트는 밀리초 단위로 돌고, 누군가 토큰 값을 손볼 때 회귀를 잡아내며, 디자인 팀을 위한 문서 역할도 함께 하는 대비 행렬을 생성합니다. 이 검사는 렌더링된 페이지와 독립적입니다. 토큰만으로 동작하므로 UI가 출시되기 전에 실패를 잡아냅니다.

이 워크플로 중간에 임시로 변환이 필요할 때, 즉 디버깅하며 hex, RGB, HSL, OKLCH 사이를 오가야 할 때는 HEX → RGB, HEX → HSL, HEX → OKLCH, RGB → HEX 스포크가 툴체인이 기대하는 모든 색상 포맷에 대한 왕복 변환을 책임집니다.

자주 마주치는 실수와 해결 방법

수년간 접근성 감사를 보다 보니, 같은 여섯 가지 실패가 반복해서 나타납니다. 각각 깔끔한 해결책이 있습니다.

  1. 플레이스홀더 텍스트가 옅은 회색. 흰색 위 #999999는 2.85:1, AA 실패입니다. #666666(5.74:1, AA 통과)으로 짙게 만드세요. 더 좋은 방법은 플레이스홀더를 라벨로 쓰는 패턴 자체를 입력란 위 상시 표시 라벨로 대체하는 것입니다. 플레이스홀더는 정보를 담아서는 안 됩니다.

  2. 브랜드 오렌지 버튼에 흰 글자. 흰색 위 #FFA500은 1.97:1, AA를 크게 벗어납니다. 브랜드를 지키는 해결책은 대비 방향을 뒤집는 것입니다. 오렌지 배경 위에 어두운 글자(예: #451a03)를 쓰거나, 흰 글자를 유지하되 버튼을 채도 높은 짙은 브라운-오렌지로 어둡게 만드세요. 배포 전에 색상 변환기로 확인하시기 바랍니다.

  3. 다크 모드에서 밝은 파란색 링크. #000000#3b82f6은 5.71:1, WCAG AA 통과지만 APCA Lc ~65로 본문 기준 Lc 75 아래입니다. OKLCH로 가서 C와 H를 고정한 채 L을 ≈ 0.63에서 0.75로 올리세요. #7aa5f8 부근에 도달하며, 같은 색조에 편안한 APCA Lc 80+를 얻습니다.

  4. #CCCCCC 색의 비활성 텍스트. 흰색 대비 1.61:1입니다. WCAG 1.4.3은 순수한 장식용 텍스트를 비율 규칙에서 면제하지만, 비활성 UI 컨트롤은 장식이 아닙니다. 그것은 “지금 사용할 수 없습니다”를 전달합니다. 흐릿한 색을 비색상 단서(취소선, 자물쇠 아이콘, “비활성화됨” 툴팁)와 짝지어 색각이상 또는 저시력 사용자도 상태를 이해할 수 있게 하세요.

  5. 색조로만 구분되는 상태 아이콘. 빨간 ×와 초록 는 모양이 이미 둘을 구분하므로 괜찮습니다. 빨간 점 vs 초록 점은 그렇지 못합니다. 모양과 색을 함께 사용하세요. 색상 변환기의 CVD 미리보기는 실패 사례를 1초 만에 명백하게 보여 줍니다.

  6. 그라데이션 배경 위의 텍스트. #3b82f6에서 #a78bfa로 흐르는 그라데이션 위의 흰 글자는 가운데서는 대비를 통과하지만 라벤더 쪽 끝에서는 실패합니다. 해결책은 그라데이션의 최악 지점에 대비를 강제하거나, 반투명 어두운 스크림을 덮어서 유효 배경 휘도가 알려진 임계값 아래에 머물도록 하는 것입니다.

각 수정은 분 단위로 끝납니다. 그것이 피하는 감사 사이클은 주 단위입니다.

자주 묻는 질문

WCAG AA 대비 비율은 무엇인가요?

WCAG AA는 본문 텍스트와 배경 사이에 ≥ 4.5:1을, 큰 글자(≥ 18pt 일반 또는 ≥ 14pt 굵게)와 폼 테두리 같은 UI 구성 요소에는 ≥ 3:1을 요구합니다. AA는 ADA, EAA, Section 508 아래에서의 법적 기준선입니다. 상업 사이트 대부분이 AA를 목표로 하는 이유는, 브랜드 색을 회색조 쪽으로 강제하지 않으면서도 규제 기준을 충족하기 때문입니다.

AAA에는 어떤 대비 비율이 필요한가요?

WCAG AAA는 일반 본문 텍스트에 ≥ 7:1, 큰 글자에 ≥ 4.5:1을 요구합니다. AAA는 사용자 기반이 더 높은 접근성 요구로 기울어 있는 의료·교육·정부 사이트에서 권장됩니다. 브랜드 색은 AAA를 통과하기 위해 종종 회색조에 가까운 값으로 평탄화되어야 하며, 그래서 많은 상업 제품이 AA에서 멈추는 것입니다.

APCA가 무엇인가요? WCAG 3.0인가요?

APCA(Advanced Perceptual Contrast Algorithm)는 Andrew Somers / Myndex가 설계했으며, WCAG 3 Silver 프로젝트의 후보 알고리즘입니다. 대칭 비율 대신 -108에서 +108까지의 극성 인지 Lc 점수를 사용합니다. 2026년 현재 WCAG 3는 여전히 초기 초안 단계이고 APCA는 공식 비준되지 않았습니다. 오늘 충족해야 하는 규제 표준은 여전히 WCAG 2.1 / 2.2 AA입니다.

다크 모드가 대비 접근성에 도움이 되나요?

때로는 그렇습니다. 다만 자동으로 그렇지는 않습니다. WCAG 2의 대칭 비율은 라이트 모드와 다크 모드에서 같은 조합을 통과시키지만, 극성 인지형인 APCA는 같은 hex 쌍이라도 라이트 모드보다 다크 모드 본문 텍스트가 더 읽기 어렵다고 자주 표시합니다. 배포 전에 다크 모드를 WCAG와 APCA 양쪽으로 항상 재검증하시기 바랍니다. 밝은 배경 위 어두운 글자보다 어두운 배경 위 밝은 글자는, 대칭 비율이 볼 수 없는 방식으로 지각 대비를 잃습니다.

내 브랜드 색이 왜 WCAG AA를 통과하지 못하나요?

채도가 높고 중간 휘도를 가진 색(대부분의 오렌지, 노랑, 라임 그린, 옅은 파랑)은 상대 휘도 값이 흰색에 너무 가까워 4.5:1을 넘지 못합니다. 해결책: 강조와 큰 표제에는 브랜드 색조를 유지하되, 본문 텍스트는 같은 색조 계열에서 더 어두운 톤으로 짝지으세요. OKLCH를 사용해 색조를 흔들지 않고 L 채널만 낮추세요. 색상 변환기가 가장 가까운 통과 셰이드를 한 단계로 찾아 줍니다.

WCAG 2 비율과 APCA 점수는 서로 호환되나요?

아닙니다. WCAG 2는 대칭 비율(1–21)을 반환하고, APCA는 극성 부호 Lc 점수(-108에서 +108)를 반환합니다. 관계는 비선형입니다. WCAG에서 4.5:1인 쌍이 어느 색이 위에 있느냐에 따라 APCA에서 Lc 60이 될 수도 Lc 75가 될 수도 있습니다. 둘을 서로의 번역으로 보지 말고, 독립된 두 검사로 다루세요.

작은 UI 아이콘에 색상 대비를 적용할 수 있나요?

그렇습니다. 단, 조건이 있습니다. WCAG 2.1 §1.4.11은 UI 구성 요소와 그래픽 객체에 ≥ 3:1을 요구합니다. 보이는 텍스트 라벨과 짝지어진 장식 아이콘이라면 대비 요구가 완화됩니다. 라벨이 의미를 운반하기 때문입니다. 단독 아이콘(예: 라벨 없는 검색 돋보기)은 둘러싼 배경 대비 3:1을 그대로 강제하세요.

시뮬레이션 없이 색맹을 어떻게 테스트하나요?

Chrome DevTools → Rendering → “Emulate vision deficiencies”를 사용해 적색맹, 녹색맹, 청색맹, 전색맹을 시뮬레이션하세요. 이상 삼색형 색각 변이(가장 흔한 녹색약은 남성의 5%)에 대해서는 색상 변환기의 8 유형 CVD 미리보기와 결합하시기 바랍니다. 감사 보고를 위해서는 각 시뮬레이션 아래에서 스크린숏을 캡처해 리뷰어가 실패 모드를 인라인으로 볼 수 있게 하세요.

결론

이 가이드 전체를 떠받치는 다섯 가지 요점입니다.

  • AA 4.5:1은 법적 하한선입니다. 모든 본문 텍스트에 대해 이를 충족하거나, 컴플라이언스 잡음을 각오하세요.
  • AAA 7:1은 의료·교육·정부 대상입니다. 상업 브랜드 대부분은 의도적으로 AA에서 멈춥니다.
  • APCA Lc는 가독성 직감 점검입니다. WCAG 2와 병행 실행하세요. 다크 모드와 채도 높은 브랜드 색에서 특히 그렇게 하시기 바랍니다.
  • 색은 유일한 신호가 되어선 안 됩니다. 모든 색 단서를 모양, 텍스트, 또는 패턴과 짝지으세요. 녹색약 하나만 해도 남성 사용자의 5%입니다.
  • OKLCH의 L이 올바른 손잡이입니다. 색이 대비를 실패할 때 색조를 흔들지 않고 고치려면 S나 B가 아니라 L을 줄이세요.

hex 코드 두 개를 색상 변환기에 넣어 WCAG 비율, APCA Lc, 색역 분류, 8 유형 CVD 미리보기를 나란히 확인하시기 바랍니다. 그 한 화면이 여섯 개의 별도 도구를 대체하며, 이 가이드가 다루는 감사들을 가장 빨리 마무리하는 길입니다.