웹 접근성이란?
웹 접근성(Web Accessibility, 줄여서 A11y)은 장애 유무와 관계없이 누구나 웹 콘텐츠를 이용할 수 있도록 만드는 것입니다.
전 세계 인구의 약 15%가 어떤 형태로든 장애를 가지고 있습니다. 시각, 청각, 운동 능력, 인지 능력 등 다양한 영역에서 웹 사용에 어려움을 겪는 사용자들이 있습니다.
접근성은 윤리적인 이유뿐 아니라 실용적인 이유도 있습니다:
- 법적 요구: 한국의 장애인차별금지법, 미국의 ADA 등
- SEO 개선: 시맨틱 HTML은 검색엔진에도 좋습니다
- UX 향상: 접근성 좋은 사이트는 모든 사용자에게 편합니다
- 시장 확대: 더 많은 사용자가 서비스를 이용할 수 있습니다
시맨틱 HTML이 기본
접근성의 80%는 올바른 HTML을 쓰는 것만으로 해결됩니다.
<!-- 나쁜 예: div를 버튼으로 사용 -->
<div class="btn" onclick="submit()">제출</div>
<!-- 좋은 예: button 태그 사용 -->
<button type="submit">제출</button><button>은 자동으로:
- 키보드로 포커스 가능 (Tab)
- Enter/Space로 클릭 가능
- 스크린 리더가 "버튼"이라고 읽어줌
<div>는 이 기능이 전혀 없어서, 하나하나 직접 구현해야 합니다.
올바른 태그 선택
| 용도 | 올바른 태그 | 잘못된 사용 |
|---|---|---|
| 클릭 가능한 요소 | <button> | <div onclick> |
| 페이지 이동 | <a href> | <span onclick> |
| 입력 필드 | <input> + <label> | <div contenteditable> |
| 네비게이션 | <nav> | <div class="nav"> |
| 제목 | <h1>~<h6> | <div class="title"> |
이미지와 대체 텍스트
<!-- 정보를 담은 이미지: 의미 있는 alt -->
<img src="chart.png" alt="2026년 프론트엔드 프레임워크 사용률 — React 42%, Vue 18%">
<!-- 장식용 이미지: 빈 alt -->
<img src="decoration.svg" alt="">
<!-- 복잡한 이미지: 상세 설명 -->
<figure>
<img src="architecture.png" alt="시스템 아키텍처 다이어그램">
<figcaption>
클라이언트 → API Gateway → 마이크로서비스 → 데이터베이스 구조
</figcaption>
</figure>alt 텍스트 규칙:
- 이미지가 전달하는 정보를 적으세요 ("사진" "이미지" 같은 말은 불필요)
- 장식용이면
alt=""로 비워두세요 (스크린 리더가 건너뜀) - alt를 아예 생략하면 안 됩니다 (파일명을 읽어버림)
키보드 네비게이션
마우스를 사용할 수 없는 사용자는 키보드만으로 사이트를 탐색합니다.
필수 키보드 동작
| 키 | 동작 |
|---|---|
| Tab | 다음 포커스 요소로 이동 |
| Shift + Tab | 이전 포커스로 이동 |
| Enter / Space | 클릭/선택 |
| Escape | 모달/드롭다운 닫기 |
| 화살표 키 | 탭, 메뉴, 라디오 버튼 내 이동 |
포커스 스타일
/* 절대 하지 마세요! */
*:focus { outline: none; }
/* 대신 예쁜 포커스 스타일을 만드세요 */
:focus-visible {
outline: 2px solid #2dd4bf;
outline-offset: 2px;
border-radius: 4px;
}:focus-visible은 키보드로 포커스할 때만 표시되고, 마우스 클릭 시에는 표시되지 않습니다.
포커스 트랩 (모달)
모달이 열렸을 때 Tab이 모달 밖으로 나가면 안 됩니다.
function trapFocus(modal) {
const focusable = modal.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const first = focusable[0];
const last = focusable[focusable.length - 1];
modal.addEventListener('keydown', (e) => {
if (e.key !== 'Tab') return;
if (e.shiftKey && document.activeElement === first) {
e.preventDefault();
last.focus();
} else if (!e.shiftKey && document.activeElement === last) {
e.preventDefault();
first.focus();
}
});
}ARIA 속성
ARIA(Accessible Rich Internet Applications)는 HTML만으로 표현하기 어려운 접근성 정보를 추가합니다.
원칙: 시맨틱 HTML로 해결 가능하면 ARIA를 쓰지 마세요. ARIA는 보충 수단입니다.
<!-- 아이콘 버튼: 텍스트가 없으므로 aria-label 필수 -->
<button aria-label="메뉴 열기">
<svg>...</svg>
</button>
<!-- 토글 상태 -->
<button aria-expanded="false" aria-controls="menu">메뉴</button>
<div id="menu" hidden>...</div>
<!-- 로딩 상태 -->
<div aria-live="polite" aria-busy="true">
로딩 중...
</div>
<!-- 필수 입력 -->
<input type="email" aria-required="true" aria-invalid="false">자주 쓰는 ARIA 속성
| 속성 | 용도 |
|---|---|
aria-label | 보이지 않는 텍스트 레이블 |
aria-expanded | 열림/닫힘 상태 |
aria-hidden="true" | 스크린 리더에서 숨김 |
aria-live | 동적 변경 알림 |
aria-required | 필수 입력 |
aria-invalid | 유효성 오류 |
role | 요소의 역할 지정 |
색상 대비
텍스트와 배경의 대비비(contrast ratio)가 충분해야 합니다.
WCAG 기준:
- 일반 텍스트: 최소 4.5:1
- 큰 텍스트 (18px bold 또는 24px 이상): 최소 3:1
- UI 요소 (버튼 테두리 등): 최소 3:1
/* 대비비 부족 (2.1:1) */
.text-low { color: #94a3b8; background: #64748b; }
/* 충분한 대비비 (7.4:1) */
.text-good { color: #e2e8f0; background: #1a2435; }색상만으로 정보를 전달하지 마세요. 에러 상태를 빨간색으로만 표시하면 색각이상 사용자는 알 수 없습니다. 아이콘이나 텍스트를 함께 사용하세요.
폼 접근성
<!-- label과 input 연결 (필수!) -->
<label for="email">이메일</label>
<input id="email" type="email" required>
<!-- 에러 메시지 연결 -->
<input id="password" type="password" aria-describedby="pw-error">
<p id="pw-error" role="alert">비밀번호는 8자 이상이어야 합니다</p>
<!-- 필드 그룹 -->
<fieldset>
<legend>결제 방법 선택</legend>
<label><input type="radio" name="payment" value="card"> 카드</label>
<label><input type="radio" name="payment" value="bank"> 계좌이체</label>
</fieldset>접근성 테스트
- 키보드만으로 사이트 탐색 — Tab, Enter, Escape로 모든 기능을 사용할 수 있는지
- 크롬 Lighthouse — 개발자 도구 > Lighthouse > Accessibility
- axe DevTools — 크롬 확장 프로그램, 상세한 접근성 검사
- 스크린 리더 — NVDA(Windows, 무료), VoiceOver(Mac, 내장)
정리
웹 접근성 체크리스트:
- 시맨틱 HTML 사용 (button, nav, main 등)
- 모든 이미지에 alt 텍스트
- 키보드로 모든 기능 사용 가능
- 포커스 스타일 보이게 유지
- 충분한 색상 대비
- label과 input 연결
- ARIA는 보충 수단으로만
이 원칙만 지키면 접근성 점수가 크게 올라갑니다.