# 색상과 접근성: 모든 사용자가 구분할 수 있는 색상 설계

> 색각이상, 저시력 사용자도 웹사이트를 쉽게 사용할 수 있도록 하는 색상 설계 가이드. WCAG 명도 대비 기준부터 실무 팁까지, 포용적 색상 선택의 모든 것을 다룹니다.

**Published:** 2026-03-06 | **Updated:** 2026-03-06

---


## 들어가며

"빨강과 초록으로 구분했으니까 괜찮을 거야."

개발하다 보면 한 번쯤 이런 생각을 해보게 됩니다. 그런데 생각보다 많은 사람들이 이 두 색을 잘 구분하지 못합니다. 북유럽 혈통 기준 통계에서는 **남성 약 1/12, 여성 약 1/200**이 적색-녹색 색각이상을 가지고 있다고 알려져 있어요. 지역과 유전적 배경에 따라 비율은 달라질 수 있지만, 빨강-초록 구분이 어려운 사용자가 꾸준히 존재한다는 사실은 변하지 않습니다.

그리고 이게 전부가 아닙니다. 저시력 사용자, 나이가 든 사용자, 밝은 햇빛 아래서 화면을 보는 사용자들도 모두 색상 대비에 영향을 받아요.

**색상 접근성**은 단순히 "색맹인 사람도 볼 수 있게"하는 것이 아닙니다. 모든 사용자가 정보를 명확하게 인식하고, 색상이 정보 전달의 **유일한 수단이 아니도록** 설계하는 거죠.

이번 글에서는 색상 접근성의 이론부터 실무 팁, 검사 도구까지 정리했습니다. 현업에서 디자이너와 이 주제를 어떻게 다룰지도 함께 살펴볼게요.

{{< img src="images/contents/og_bg_thumb.png" alt="색상과 접근성 - 색상은 접근성에서 굉장히 중요한 영역 중 하나입니다." caption="제작: Nanobanana" >}}

{{< img src="images/contents/color-accessibility-overview.png" alt="색상 접근성의 다양한 측면을 시각화. 왼쪽에는 일반적인 시각으로 보는 웹페이지, 오른쪽에는 색각이상자가 보는 같은 페이지." caption="제작: Nanobanana" >}}

---

## 색상 접근성이란?

### 정의

**색상 접근성**은 색상을 포함한 모든 사용자가 웹사이트의 정보를 정확하게 인식할 수 있도록 하는 설계 원칙입니다.

여기에는 다음이 포함됩니다:

1. **색각이상 사용자**: 특정 색상을 구분하기 어려운 사람들
2. **저시력 사용자**: 명도 대비가 낮으면 텍스트를 읽을 수 없는 사람들
3. **노인**: 나이가 들면서 색상 구분 능력이 저하되는 사람들
4. **환경적 제약**: 밝은 햇빛 아래나 저품질 모니터에서 보는 사용자들

### 표준과 요구사항

색상 접근성은 WCAG 2.2에서 명확히 다룹니다:

- **SC 1.4.3 (Contrast Minimum)**: 일반 텍스트 4.5:1, 큰 텍스트 3:1
- **SC 1.4.6 (Contrast Enhanced)**: AAA 수준 7:1 / 4.5:1
- **SC 1.4.11 (Non-text Contrast)**: 아이콘·입력 필드·포커스 표시 등 비텍스트 요소 3:1
- **SC 2.4.11 / 2.4.12**: 포커스가 다른 요소에 가려지지 않도록 보장
- **SC 2.4.13 (Focus Appearance, AAA)**: 포커스 표시의 크기·대비 기준 제시

많은 조직과 규제가 WCAG 2.x를 참고하기 때문에, 이 기준을 이해하면 실무 적용이 훨씬 수월해집니다.

### 포용성 비즈니스 케이스

색상 접근성은 법적 의무만이 아닙니다:

- 더 많은 사용자가 정보를 정확히 읽고 이해할 수 있음
- 검색 최적화 (명확한 색상 대비는 텍스트 가독성 향상)
- 브랜드 이미지 (접근성 있는 회사로의 인식)
- 사용성 개선 (모든 사용자가 더 잘 읽을 수 있음)

---

## 색각이상 이해하기

### 색각이상의 유형

**1. 적색 약시 (Protanomaly)**: 빨강을 볼 때 회색처럼 보임
- 빨강 파장에 반응이 약함

**2. 적색 맹 (Protanopia)**: 빨강을 완전히 못 봄
- 세상이 파랑-노랑으로만 보임

**3. 녹색 약시 (Deuteranomaly)**: 초록을 볼 때 회색처럼 보임
- 가장 흔한 유형으로 알려짐

**4. 녹색 맹 (Deuteranopia)**: 초록을 완전히 못 봄

**5. 청색-황색 색각이상 (Tritanomaly/Tritanopia)**: 파랑과 노랑 구분 어려움
- 매우 드문 유형으로 알려짐

{{< img src="images/contents/color-blindness-types.png" alt="다양한 색각이상 유형의 색상 인식 시뮬레이션. 같은 웹페이지가 6가지 다른 방식으로 표현됨: 일반 시각(Normal vision), 적색 약시(Protanomaly), 적색 맹(Protanopia), 녹색 약시(Deuteranomaly), 녹색 맹(Deuteranopia), 청색-황색 약시(Tritanomaly). 각 시각에서 색상이 어떻게 다르게 보이는지 명확히 확인해보세요." caption="제작: Nanobanana" >}}

---

## 명도 대비(Luminance Contrast)

### WCAG 기준

WCAG 2.2에서는 텍스트와 배경의 명도 대비를 숫자로 정의합니다:

| 레벨 | 일반 텍스트 | 큰 텍스트 |
|------|-----------|---------|
| A | (요구사항 없음) | (요구사항 없음) |
| AA | 4.5:1 | 3:1 |
| AAA | 7:1 | 4.5:1 |

**큰 텍스트**의 정의:
- 18pt 이상, 또는
- 14pt 이상이고 굵은 글씨 (700 이상)

**추가로 확인할 것 (WCAG 2.2):**
- **비텍스트 대비 (SC 1.4.11)**: 아이콘, 테두리, 입력 필드 등 비텍스트 요소의 대비를 최소 3:1로 유지합니다.
- **포커스 가림 방지 (SC 2.4.11/2.4.12)**: 포커스 표시가 다른 UI에 가려지지 않도록 보장합니다.
- **포커스 표시 형태 (SC 2.4.13, AAA)**: 포커스 표시의 크기·대비 기준을 제시합니다. (높은 등급 목표 시 참고)

### 명도(Luminance) 계산

```javascript
// RGB를 명도로 변환하는 공식 (WCAG)
function getLuminance(r, g, b) {
  // 0-255 범위를 0-1로 정규화
  r = r / 255;
  g = g / 255;
  b = b / 255;

  // 감마 보정
  if (r <= 0.03928) {
    r = r / 12.92;
  } else {
    r = Math.pow((r + 0.055) / 1.055, 2.4);
  }

  if (g <= 0.03928) {
    g = g / 12.92;
  } else {
    g = Math.pow((g + 0.055) / 1.055, 2.4);
  }

  if (b <= 0.03928) {
    b = b / 12.92;
  } else {
    b = Math.pow((b + 0.055) / 1.055, 2.4);
  }

  return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}

function getContrast(foreground, background) {
  const l1 = getLuminance(...foreground); // RGB 배열
  const l2 = getLuminance(...background);

  const lighter = Math.max(l1, l2);
  const darker = Math.min(l1, l2);

  return (lighter + 0.05) / (darker + 0.05);
}

// 예시: 검은 텍스트 #000000 vs 흰 배경 #FFFFFF
const contrast = getContrast([0, 0, 0], [255, 255, 255]);
console.log(contrast); // 21 (아주 좋음!)
```

### 실용적인 대비 조합

**반드시 확인하세요**:

```css
/* ✅ 좋은 예 - 4.5:1 이상 */
.good-contrast {
  color: #000000;        /* 검은색 */
  background: #FFFFFF;   /* 흰색 */
  /* 대비: 21:1 */
}

/* ❌ 나쁜 예 - 3:1 미만 */
.bad-contrast {
  color: #777777;        /* 회색 */
  background: #CCCCCC;   /* 밝은 회색 */
  /* 대비: 약 2.79:1 */
}

/* ✅ 다크 모드 예 */
@media (prefers-color-scheme: dark) {
  body {
    color: #EEEEEE;      /* 밝은 회색 텍스트 */
    background: #1a1a1a; /* 어두운 배경 */
    /* 대비: 약 15:1 */
  }
}
```

{{< img src="images/contents/contrast-ratio-examples.png" alt="WCAG 대비 비율 가이드라인 - 마치 신호등처럼 빨강(실패) 에서 4.5:1을 준수한 노랑(AA 통과) 에서 7:1을 준수한 녹생(AAA 패스) 를 단계별로 비교합니다." caption="제작: Nanobanana" >}}

### 도구를 이용한 검사

1. **WebAIM Contrast Checker**: https://webaim.org/resources/contrastchecker/
2. **Chrome DevTools**: Elements > Inspect > 색상 선택기
3. **Contrast Ratio 웹사이트**: https://contrast-ratio.com/

---

## 색상만으로 정보 전달하면 안 된다

### 문제 상황

```html
<!-- ❌ 나쁜 예 -->
<div>
  <span style="color: red">오류</span>
  <span style="color: green">성공</span>
</div>

<!-- 색각이상자는 둘 다 같은 색으로 보임 -->
```

### 해결 방법

```html
<!-- ✅ 좋은 예 1: 텍스트 포함 -->
<div>
  <span style="color: red">❌ 오류</span>
  <span style="color: green">✅ 성공</span>
</div>

<!-- ✅ 좋은 예 2: 아이콘 + 텍스트 -->
<div>
  <span style="color: red" aria-label="오류">
    <i class="icon-error"></i> 오류 메시지
  </span>
</div>

<!-- ✅ 좋은 예 3: 패턴 사용 -->
<svg width="100" height="100">
  <!-- 빨강 + 대각선 패턴 -->
  <rect fill="red" width="50" height="50"/>
  <pattern id="diag" patternUnits="userSpaceOnUse" width="8" height="8">
    <path d="M0,8 l8,-8 M-2,2 l4,-4 M6,10 l4,-4" stroke="black" stroke-width="1"/>
  </pattern>
  <rect fill="url(#diag)" width="50" height="50"/>
</svg>
```

### 폼 입력 검증 예제

```html
<!-- ❌ 색상만 사용 -->
<input type="email" style="border: 2px solid red;">

<!-- ✅ 색상 + 아이콘 + 메시지 -->
<div class="form-group">
  <input
    type="email"
    class="form-input has-error"
    aria-describedby="email-error">
  <svg class="error-icon" aria-hidden="true">
    <use xlink:href="#icon-error"></use>
  </svg>
  <p id="email-error" class="error-message">
    유효한 이메일 주소를 입력하세요
  </p>
</div>
```

```css
.form-input.has-error {
  border: 2px solid #d32f2f; /* 빨강 */
  background-color: #ffebee; /* 연한 빨강 */
}

.error-icon {
  color: #d32f2f; /* 빨강 */
}

.error-message {
  color: #d32f2f;
  /* 텍스트로 문제를 명확하게 설명 */
}
```

---

## 색상 선택 가이드

### 1단계: 먼저 명도로 설계

```css
/* 색상 없이 흑백으로 먼저 설계 */
body {
  color: #333333; /* 어두운 회색 텍스트 */
  background: #ffffff; /* 흰 배경 */
}

/* 이 상태에서 이미 4.5:1 이상의 대비 */
```

### 2단계: 색상 추가

```css
/* 명도를 유지하면서 색상 추가 */
.primary {
  color: #0962db; /* 파랑 - 명도 유지 */
  background: #ffffff;
  /* 명도 대비: 약 5.6:1 */
}

.secondary {
  color: #1e7e34; /* 초록 - 명도 유지 */
  background: #ffffff;
  /* 명도 대비: 약 5.1:1 */
}
```

### 3단계: 색맹 시뮬레이션 테스트

```javascript
// Deuteranopia (녹색 맹)를 위한 색상 변환
function simulateDeuteranopia(rgb) {
  const [r, g, b] = rgb;
  return [
    0.625 * r + 0.375 * g,
    0.7 * r + 0.3 * g,
    b
  ];
}

// 테스트
const primary = [9, 98, 219]; // 파랑 #0962db
const simulated = simulateDeuteranopia(primary);
// 결과: [42, 36, 219] - 파랑이 약간 다르게 보이지만 구분 가능
// 참고: 실제 색각이상 시뮬레이션은 LMS 색공간 변환이 필요합니다. 이 함수는 교육용 근사치입니다.
```

### 권장 색상 팔레트

```css
/* 예시 팔레트 (AA 이상을 목표로 설계) */

/* 회색 톤 */
:root {
  --gray-900: #111827; /* 거의 검은색 */
  --gray-700: #374151; /* 어두운 회색 */
  --gray-500: #6b7280; /* 중간 회색 */
  --gray-100: #f3f4f6; /* 밝은 회색 */
  --gray-50: #f9fafb;  /* 거의 흰색 */
}

/* 기능색 (사용 맥락에 따라 대비 재검증 필요) */
:root {
  --success: #065f46;   /* 짙은 초록 */
  --danger: #7f1d1d;    /* 짙은 빨강 */
  --warning: #92400e;   /* 짙은 노랑/갈색 */
  --info: #0c4a6e;      /* 짙은 파랑 */
}

/* 흰 배경 위 사용 */
.success { color: var(--success); background: white; }
.danger { color: var(--danger); background: white; }
.warning { color: var(--warning); background: white; }
.info { color: var(--info); background: white; }
```

{{< img src="images/contents/accessible-color-palette-comparison.png" alt="접근성 있는 색상 팔레트 비교. 왼쪽은 일반적인 밝은 색상 팔레트(접근성 부족), 오른쪽은 짙은 톤의 팔레트(접근성 우수). 각 색상의 명도 값과 WCAG 대비 비율을 함께 표시. 색각이상 시뮬레이션도 함께 확인할 수 있습니다." caption="제작: Nanobanana" >}}

---

## 현업에서 자주 마주하는 상황: "이건 우리 브랜드 색이에요"

디자이너와 함께 일하다 보면 이런 순간이 찾아옵니다.

> "로고에서 따온 색상이라 바꾸기 어려워요. 이미 브랜드 가이드에 들어가 있고, 마케팅팀이랑도 맞춰둔 거라서요."

색상 대비 문제를 제기했더니 돌아온 답변입니다. 이 상황, 낯설지 않으시죠?

브랜드 색상은 오랜 시간을 거쳐 결정된 결과물인 경우가 많습니다. 디자이너 입장에서는 "접근성 때문에 바꾸자"는 말이 단순한 수정 요청이 아니라 브랜드 아이덴티티를 건드리는 것처럼 느껴질 수 있거든요.

### 구체적인 상황을 가정해봅시다

버튼 텍스트 색상이 브랜드 파랑 `#4B9DFF`이고, 배경은 흰색(`#FFFFFF`)입니다.

```
배경:  #FFFFFF (흰색)
텍스트: #4B9DFF (밝은 파랑)
대비:  약 3.0:1 → AA 실패 (일반 텍스트 기준 4.5:1 필요)
```

이 상황에서 "이 색은 안 됩니다"라고 말하면 대화가 막히는 경우가 많습니다. 대신 다음 단계로 접근하는 게 효과적입니다.

**1단계: 데이터로 함께 확인하기**

WebAIM Contrast Checker나 Chrome DevTools를 열고, 디자이너와 함께 실제 수치를 확인합니다. "규정 때문에 드리는 말씀이 아니라, 이 색상이 저시력 사용자에게 어떻게 보이는지 같이 확인해볼 수 있을까요?"라는 접근이 훨씬 잘 통합니다.

**2단계: 대안 제시하기**

"이 색상은 안 됩니다"보다 "이렇게 하면 브랜드 색감은 살리면서 기준도 맞출 수 있어요"가 협업의 문을 열어줍니다.

```css
/* 기존 브랜드 색 - AA 실패 */
.btn {
  color: #4B9DFF;  /* 대비: 약 3.0:1 ❌ */
  background: #FFFFFF;
}

/* 방법 1: 같은 계열, 더 어둡게 */
.btn {
  color: #0062D1;  /* 대비: 약 5.1:1 ✅ */
  background: #FFFFFF;
}

/* 방법 2: 배경과 텍스트 반전 */
.btn {
  color: #FFFFFF;
  background: #0062D1;  /* 대비: 약 5.1:1 ✅ */
}
```

같은 파랑 계열에서 채도와 명도를 조정하면 브랜드 정체성을 크게 훼손하지 않으면서도 WCAG AA를 충족시킬 수 있는 경우가 많습니다.

**3단계: 합의 내용 문서화하기**

합의된 내용은 디자인 시스템이나 브랜드 가이드에 "접근성을 고려한 색상 사용 규칙"으로 함께 기록해 두는 게 좋습니다. 그래야 다음에 같은 대화를 반복하지 않아도 되거든요.

### 설득이 어려운 경우도 있습니다

가끔은 현실적인 제약이 앞을 막습니다. "브랜드 가이드라인 변경은 경영진 승인이 필요하다", "이미 인쇄물까지 나간 색상이다" 같은 상황이죠.

이럴 때 현업에서 자주 사용하는 방법들이 있습니다. 브랜드 색상을 그대로 유지하면서도 가독성을 높이는 기법들입니다.

**방법 1: text-shadow로 아웃라인 효과 (이미지·그라디언트 배경에 효과적)**

밝은 색상 텍스트가 복잡한 배경 위에 올라갈 때 가장 자주 쓰는 방법입니다. 지도 레이블, 히어로 섹션 타이틀에서 흔히 볼 수 있는 패턴이에요.

```css
.hero-title {
  color: #4B9DFF; /* 브랜드 파랑 */
  /* 어두운 아웃라인으로 배경과의 대비를 확보 */
  text-shadow:
    -1px -1px 0 rgba(0, 30, 80, 0.85),
     1px -1px 0 rgba(0, 30, 80, 0.85),
    -1px  1px 0 rgba(0, 30, 80, 0.85),
     1px  1px 0 rgba(0, 30, 80, 0.85);
}
```

주의할 점이 있습니다. text-shadow는 WCAG 명도 대비 계산에 포함되지 않습니다. 자동화 도구는 여전히 "실패"로 표시할 수 있지만, 실제 사용자 가독성은 크게 향상됩니다. 도구 점수보다 실제 사용성을 함께 평가하는 게 좋습니다.

**방법 2: text-stroke + paint-order (헤딩·디스플레이 텍스트에 효과적)**

Modern CSS로 텍스트에 스트로크를 추가하는 방법입니다. `paint-order`를 함께 쓰면 스트로크가 텍스트 안쪽을 침범하지 않아요.

```css
.display-heading {
  color: #4B9DFF; /* 브랜드 파랑 */
  -webkit-text-stroke: 3px #003380; /* 어두운 파랑 스트로크 */
  paint-order: stroke fill; /* 스트로크를 fill 아래에 렌더링 */
}
```

폰트 크기가 클수록 효과적입니다. 본문 텍스트에는 어색해 보일 수 있으니 큰 제목이나 강조 텍스트에 사용하세요.

**방법 3: 텍스트 배경 칩 (UI 컴포넌트·배지에 효과적)**

브랜드 색상을 장식 요소(테두리, 아이콘)에 유지하고, 텍스트에는 별도의 배경을 깔아 대비를 확보하는 방법입니다. 가장 안정적이고 WCAG 기준도 충족합니다.

```css
.tag {
  /* 브랜드 색상은 테두리로 유지 */
  border: 2px solid #4B9DFF;
  border-radius: 4px;

  /* 텍스트는 충분한 대비 확보 */
  color: #003380;        /* 어두운 파랑: 흰 배경 대비 약 10:1 ✅ */
  background: #FFFFFF;
  padding: 4px 10px;
}

/* 또는 브랜드 색 배경 위에 흰 텍스트 */
.tag-filled {
  background: #4B9DFF;
  color: #FFFFFF;
  /* 대비: 약 3.0:1 → 큰 텍스트 기준은 충족, 본문 기준은 아직 부족 */
  /* 폰트를 14pt bold 이상으로 설정하면 AA 기준 통과 */
  font-size: 1rem;
  font-weight: 700;
}
```

**방법 4: 반투명 스크림 (이미지 위 텍스트에 효과적)**

사진이나 그라디언트 배경 위에 텍스트가 올라가는 경우, 배경과 텍스트 사이에 반투명 레이어를 추가합니다.

```css
.card-text-area {
  /* 텍스트 영역에 반투명 어두운 배경 */
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.75) 0%,
    rgba(0, 0, 0, 0) 100%
  );
  padding: 24px 16px 16px;
}

.card-title {
  color: #FFFFFF; /* 흰 텍스트 */
  /* 스크림 덕분에 충분한 대비 확보 */
}
```

---

어떤 방법을 쓰든, 한 가지를 기억해 두면 좋습니다. 자동화 도구가 "실패"로 표시해도, 실제 사용자가 충분히 읽을 수 있다면 그것도 개선입니다.
접근성은 "완벽하거나 아무것도 아니거나"가 아닙니다. 할 수 있는 데서부터 시작하면 됩니다.

---

## 실무: 다크 모드와 색상

### 다크 모드의 색상 대비 이슈

```css
/* ❌ 라이트 모드 색상을 다크 모드에 그대로 사용 */
@media (prefers-color-scheme: dark) {
  body {
    background: #1a1a1a;
    color: #0066cc; /* 라이트 모드의 파랑 */
    /* 대비: 약 3.1:1 - 일반 텍스트에는 부족 */
  }
}

/* ✅ 다크 모드에 맞게 조정 */
@media (prefers-color-scheme: dark) {
  body {
    background: #1a1a1a;
    color: #66b2ff; /* 밝은 파랑 */
    /* 대비: 약 7.8:1 - 충분함 */
  }
}
```

### 테마 변수로 관리

```css
:root {
  /* 라이트 모드 */
  --text-primary: #111827;
  --text-secondary: #6b7280;
  --background-primary: #ffffff;
  --background-secondary: #f3f4f6;

  --accent-primary: #0962db;
  --accent-danger: #7f1d1d;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* 다크 모드 - 명도를 고려해 조정 */
    --text-primary: #f3f4f6;
    --text-secondary: #d1d5db;
    --background-primary: #1a1a1a;
    --background-secondary: #374151;

    --accent-primary: #66b2ff;
    --accent-danger: #fca5a5;
  }
}

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

.button-primary {
  color: white;
  background: var(--accent-primary);
}
```

---

## 검사와 테스트

### 수동 검사 체크리스트

```markdown
## 색상 접근성 체크리스트

### 명도 대비
- [ ] 텍스트와 배경 대비가 4.5:1 이상?
- [ ] 큰 텍스트(18pt+)도 3:1 이상?
- [ ] 버튼과 배경 대비도 확인했나?

### 색상 의존성
- [ ] 색상만으로 정보를 표현하지 않았나?
- [ ] 형태/패턴/텍스트로도 구분되나?
- [ ] 에러 메시지가 색상+텍스트로 표현되나?

### 색각이상 테스트
- [ ] 페이지를 색맹 시뮬레이터로 확인했나?
- [ ] 빨강-초록 구분이 중요한가?
- [ ] 다른 색상 조합도 테스트했나?

### 다크 모드
- [ ] 다크 모드에서도 대비가 충분한가?
- [ ] 색상이 자동으로 조정되나?
```

### 자동화 도구

```javascript
// axe DevTools 검사 (브라우저 확장)
// https://www.deque.com/axe/devtools/

// 또는 프로그래매틱하게
async function checkContrast() {
  const { axe } = window;
  const results = await axe.run({
    rules: ['color-contrast']
  });

  results.violations.forEach(violation => {
    console.log('색상 대비 문제:', violation);
  });
}
```

### 권장 도구

{{< img src="images/contents/color-testing-tools.png" alt="색상 접근성 검사 도구들은 다양합니다. WebAIM Contrast Checker, 색맹 시뮬레이터, axe DevTools, Lighthouse, WCAG 가이드라인의 예시." caption="제작: Nanobanana" >}}

1. **WebAIM Contrast Checker**: 두 색상의 대비 검사
2. **Color Blindness Simulator**: 색맹 시뮬레이션
3. **axe DevTools**: 자동화된 접근성 검사
4. **Lighthouse**: Chrome DevTools 내장 검사

자세한 사용방법은 추후 포스트에서 다뤄보겠습니다.

---

## 자주 실수하는 패턴

### 실수 1: 회색 텍스트로 부가 정보 표현

```css
/* ❌ 회색 텍스트는 저시력 사용자가 못 읽을 수 있음 */
.secondary-text {
  color: #999999; /* 회색 */
  background: #ffffff;
  /* 대비: 약 2.85:1 - AA 미달 */
}

/* ✅ 어두운 회색 사용 */
.secondary-text {
  color: #666666; /* 어두운 회색 */
  background: #ffffff;
  /* 대비: 약 5.74:1 - AA 만족 */
}
```

### 실수 2: 포커스 스타일을 너무 옅게 설정

```css
/* ❌ 포커스 아웃라인이 옅음 */
button:focus {
  outline: 1px solid #cccccc;
  outline-offset: 1px;
}

/* ✅ 명확한 포커스 스타일 */
button:focus-visible {
  outline: 3px solid #0962db;
  outline-offset: 2px;
}
```

### 실수 3: 라이트/다크 모드 색상을 동일하게 사용

```css
/* ❌ 둘 다 파랑 #0066cc 사용 */
.primary-color {
  color: #0066cc;
}

/* ✅ 모드별로 조정 */
:root {
  --primary: #0066cc;
}

@media (prefers-color-scheme: dark) {
  :root {
    --primary: #66b2ff;
  }
}

.primary-color {
  color: var(--primary);
}
```

---

## 정리하며

색상 접근성은 **모든 설계자와 개발자가 알아야 할 기본 원칙**입니다.
그리고 디자이너와의 협업에서 알 수 있듯, 이건 혼자서 해결하는 문제가 아니라 **팀이 함께 만들어가는 품질**이기도 하죠.

체크리스트로 정리하면 이렇습니다.

- ✅ 명도 대비 검사 (4.5:1 이상)
- ✅ 색상만으로 정보 표현 금지
- ✅ 색맹 시뮬레이터로 테스트
- ✅ 다크 모드에서도 대비 확인
- ✅ 포커스 스타일이 명확
- ✅ 자동화 도구로 검사

이 항목들을 하나씩 챙기다 보면, 단지 색각이상 사용자만이 아니라 저시력 사용자, 노인, 그리고 평범한 사용자까지 모두가 더 쉽게 쓸 수 있는 웹이 됩니다.
작은 색상 하나가 누군가의 경험을 바꿀 수 있다는 것, 기억해 두셨으면 좋겠습니다.

---

## 참고 자료


- [WebAIM: Color Contrast Checker](https://webaim.org/resources/contrastchecker/)
- [WCAG 2.2: Color Contrast](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html)
- [WCAG 2.2: Non-text Contrast](https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html)
- [MedlinePlus: Color Vision Defects](https://medlineplus.gov/colorvisiondefects.html)
- [Color Blindness Simulator](https://www.color-blindness.com/coblis-color-blindness-simulator/)
- [Accessible Colors](https://accessible-colors.com/)
- [The A11Y Project: Color](https://www.a11yproject.com/posts/what-is-color-contrast/)

