[TIL] [실전] 개발자가 당장 알아야 할 웹 접근성(a11y) 핵심 요약

[실전] 개발자가 당장 알아야 할 웹 접근성(a11y) 핵심 요약

들어가며

웹 접근성(Web Accessibility)은 단순히 장애인을 위한 배려가 아닙니다. 마우스를 쓰기 귀찮아하는 ‘키보드 파워 유저’, 햇빛 쨍쨍한 야외에서 폰을 보는 사용자 모두를 위한 것입니다.

거창한 이론보다, 실무에서 개발자가 자주 놓치는 실수와 핵심 패턴 5가지를 정리했습니다.


1. tabindex: 제발 양수(1 이상) 쓰지 마세요

접근성 테스트를 할 때 가장 먼저 깨지는 곳이 바로 탭 순서입니다. “자연스러운 탭 순서(Natural Tab Order)”란 HTML 코드가 작성된 순서(DOM)대로 포커스가 이동하는 것을 말합니다.

🚫 tabindex="1" 이상 (절대 금지)

<input type="text" tabindex="1">
  • 이유: HTML 구조를 무시하고 강제로 순서를 가로챕니다. 시각 장애인이나 키보드 사용자는 맥락을 잃고 길을 잃게 됩니다.

tabindex="0" (흐름에 끼워주기)

<div role="button" tabindex="0" onclick="save()">저장</div>
  • 용도: div나 span처럼 원래 포커스를 못 받는 요소를 자연스러운 탭 흐름에 참여시킬 때 씁니다.

✅ tabindex=”-1” (흐름에서 빼기)

<div id="modal" tabindex="-1">모달 창</div>
  • 용도: 탭 키로는 도달할 수 없지만, 자바스크립트(element.focus())로 포커스를 보내야 할 때(모달, 에러 메시지 등) 사용합니다.

2. 색상 콘트라스트? 아니, ‘명도 대비’

흔히 ‘색상 콘트라스트’라고 부르지만, 정확한 표현은 ‘명도 대비(Luminosity Contrast)’ 입니다. 색맹이 있는 사용자도 ‘밝고 어두움’의 차이는 인지할 수 있기 때문입니다.

🎨 핵심 기준 (WCAG AA)

  • 일반 텍스트: 4.5 : 1 이상
  • 큰 텍스트(18pt+): 3 : 1 이상
  • UI 컴포넌트(버튼 테두리 등): 3 : 1 이상

💡 실무 팁

  1. 회색 글자 주의: 흰 배경에 #999 같은 연한 회색은 십중팔구 기준 미달입니다. 최소 #767676 이상 써야 통과합니다.
  2. 색상에만 의존 금지: 에러 메시지를 빨간색으로만 표시하지 마세요. 빨간색을 못 보는 사용자를 위해 아이콘이나 텍스트(“Error”) 를 같이 써야 합니다.

3. ARIA는 ‘최후의 수단’이다

ARIA(Accessible Rich Internet Applications)는 HTML만으로 부족할 때 쓰는 보조 장치입니다.

⚠️ ARIA 제 1원칙: 안 쓸 수 있으면 쓰지 마라

네이티브 HTML 태그가 이미 그 역할을 하고 있다면, ARIA를 덧붙이지 마세요.

<button role="button">버튼</button>

<button>버튼</button>

⚠️ ARIA 제 2원칙: 거짓말 하지 마라

모양은 버튼인데 역할은 링크라면 혼란이 옵니다.

<div role="button" onclick="location.href='/'">홈으로</div>

<a href="/">홈으로</a>

4. ‘예쁜’ 버튼의 함정 (키보드 이벤트)

<div><span>으로 버튼을 만들고 onClick만 달아두셨나요? 마우스 사용자는 문제없지만, 키보드 사용자는 그 버튼을 영원히 누를 수 없습니다.

커스텀 버튼을 만들 때 필수 체크리스트:

  1. tabindex=”0”이 있는가? (포커스 가능)
  2. Enter와 Space 키 이벤트를 처리했는가? (실행 가능)
// React 예시
<div
  role="button"
  tabIndex={0}
  onClick={handleClick}
  onKeyDown={(e) => {
    if (e.key === "Enter" || e.key === " ") {
      handleClick();
    }
  }}
>
  커스텀 버튼
</div>

물론, 가장 좋은 건 <button> 태그를 쓰고 CSS로 스타일을 덮어씌우는 것입니다.

5. 포커스 아웃라인(Outline) 삭제 금지

디자인을 해친다고 CSS에서 outline: none을 넣어버리는 경우가 많습니다.

/* ❌ 절대 금지 */
*:focus { outline: none; }

이렇게 하면 키보드 사용자는 지금 내가 어디를 누르고 있는지 전혀 알 수 없습니다. 디자인이 중요하다면 아웃라인을 없애지 말고 예쁘게 다시 정의(Custom Styling) 하세요.

/* ✅ 대안: 커스텀 포커스 스타일 */
*:focus-visible {
  outline: 2px solid #4A90E2;
  outline-offset: 2px;
}

마치며: 완벽함보다 중요한 건 ‘시작’

웹 접근성은 하루아침에 100점을 맞을 수 없습니다. 우선 시맨틱 태그(button, a, input) 를 제대로 쓰는 것부터 시작해 보세요. 그것만으로도 80% 이상의 문제는 해결됩니다.

지금 개발 중인 화면에서 Tab 키를 한번 눌러보세요. 포커스가 물 흐르듯 자연스럽게 이동하나요? 그렇다면 이미 훌륭한 접근성을 갖춘 것입니다.