웹 접근성
웹 접근성(Web Accessibility)이란 장애인, 고령자 등 모든 사용자가 웹 콘텐츠와 서비스를 동등하게 이용할 수 있도록 보장하는 것입니다.
왜 필요한가
[웹 접근성이 없는 경우]
시각 장애인: 스크린 리더로 웹 페이지 읽기 → 이미지에 설명 없음 → 내용 파악 불가 X
색각 이상자: 빨간색/초록색으로만 구분된 UI → 구분 불가 X
지체 장애인: 마우스 사용 불가 → 키보드로 버튼 접근 안 됨 X
고령자: 작은 글씨, 낮은 대비 → 읽기 어려움 X
[웹 접근성이 보장된 경우]
시각 장애인: 이미지에 대체 텍스트 → 스크린 리더가 읽어줌 O
색각 이상자: 색상 + 아이콘/텍스트로 함께 표현 → 구분 가능 O
지체 장애인: 모든 기능이 키보드로 조작 가능 O
고령자: 충분한 글씨 크기, 높은 대비 → 읽기 편함 O
웹 접근성의 4대 원칙 (WCAG)
W3C에서 제정한 WCAG(Web Content Accessibility Guidelines)의 4대 원칙입니다.
| 원칙 | 영문 | 의미 |
|---|---|---|
| 인식의 용이성 | Perceivable | 모든 콘텐츠를 인식할 수 있어야 함 |
| 운용의 용이성 | Operable | 모든 기능을 조작할 수 있어야 함 |
| 이해의 용이성 | Understandable | 콘텐츠를 이해할 수 있어야 함 |
| 견고성 | Robust | 다양한 기술 환경에서 동작해야 함 |
원칙별 상세 및 구현 예시
1. 인식의 용이성 (Perceivable)
모든 정보를 사용자가 인식할 수 있는 형태로 제공해야 합니다.
이미지 대체 텍스트
<!-- X 잘못된 예시 — 스크린 리더가 "이미지"라고만 읽음 -->
<img src="product.jpg">
<!-- X 의미 없는 대체 텍스트 -->
<img src="product.jpg" alt="이미지">
<!-- O 올바른 예시 — 이미지의 의미를 전달 -->
<img src="product.jpg" alt="삼성 갤럭시 버즈3 화이트 색상 정면 사진">
<!-- O 장식용 이미지는 빈 alt로 스크린 리더가 무시하게 함 -->
<img src="decoration.png" alt="">
영상 자막 제공
<!-- O 동영상에 자막 트랙 포함 -->
<video controls>
<source src="tutorial.mp4" type="video/mp4">
<track kind="subtitles" src="captions_ko.vtt" srclang="ko" label="한국어" default>
</video>
색상만으로 정보를 구분하지 않기
<!-- X 색상만으로 상태 표현 -->
<span style="color: red;">실패</span>
<span style="color: green;">성공</span>
<!-- O 색상 + 텍스트/아이콘으로 함께 표현 -->
<span style="color: red;">X 실패</span>
<span style="color: green;">O 성공</span>
명도 대비 보장
/* X 낮은 대비 — 읽기 어려움 */
.text {
color: #aaaaaa; /* 밝은 회색 */
background-color: #ffffff; /* 흰색 */
/* 대비율: 2.3:1 */
}
/* O 충분한 대비 — WCAG 기준 4.5:1 이상 */
.text {
color: #333333; /* 어두운 회색 */
background-color: #ffffff; /* 흰색 */
/* 대비율: 12.6:1 */
}
2. 운용의 용이성 (Operable)
모든 기능을 키보드만으로도 조작할 수 있어야 합니다.
키보드 접근성
<!-- X 키보드로 접근 불가 -->
<div onclick="submit()">제출하기</div>
<!-- O 키보드로 접근 가능 (Tab으로 이동, Enter로 실행) -->
<button onclick="submit()">제출하기</button>
<!-- O div를 써야 한다면 role과 tabindex 추가 -->
<div role="button" tabindex="0"
onclick="submit()"
onkeydown="if(event.key === 'Enter') submit()">
제출하기
</div>
포커스 표시
/* X 포커스 표시 제거 — 키보드 사용자가 현재 위치를 알 수 없음 */
*:focus {
outline: none;
}
/* O 포커스 표시 유지 또는 커스터마이징 */
button:focus {
outline: 2px solid #4A90D9;
outline-offset: 2px;
}
충분한 시간 제공
<!-- O 자동 슬라이드에 일시정지 버튼 제공 -->
<div class="carousel">
<div class="slides">...</div>
<button onclick="pauseCarousel()">일시정지</button>
</div>
<!-- O 세션 만료 전 연장 알림 -->
<script>
// 세션 만료 2분 전 경고
setTimeout(() => {
if (confirm("세션이 곧 만료됩니다. 연장하시겠습니까?")) {
extendSession();
}
}, sessionTimeout - 120000);
</script>
3. 이해의 용이성 (Understandable)
콘텐츠와 UI가 예측 가능하고 이해하기 쉬워야 합니다.
언어 명시
<!-- O 문서 기본 언어 명시 — 스크린 리더가 올바른 발음으로 읽음 -->
<html lang="ko">
<!-- O 부분적으로 다른 언어 사용 시 -->
<p>이 제품은 <span lang="en">Made in Korea</span>입니다.</p>
입력 오류 안내
<!-- X 어디가 잘못인지 알 수 없음 -->
<p style="color: red;">입력 오류</p>
<!-- O 구체적인 오류 위치와 수정 방법 안내 -->
<label for="email">이메일</label>
<input type="email" id="email" aria-describedby="email-error" aria-invalid="true">
<p id="email-error" role="alert" style="color: red;">
이메일 형식이 올바르지 않습니다. 예: hong@example.com
</p>
일관된 네비게이션
모든 페이지에서 동일한 위치에 동일한 메뉴 구조 유지
[모든 페이지 공통]
┌─────────────────────────────────────┐
│ 로고 │ 홈 │ 상품 │ 장바구니 │ ← 항상 같은 위치
├─────────────────────────────────────┤
│ │
│ 페이지 내용 │
│ │
└─────────────────────────────────────┘
4. 견고성 (Robust)
다양한 브라우저, 보조 기술에서 올바르게 해석될 수 있어야 합니다.
시맨틱 HTML
<!-- X div만으로 구성 — 스크린 리더가 구조를 파악할 수 없음 -->
<div class="header">...</div>
<div class="nav">...</div>
<div class="content">...</div>
<div class="footer">...</div>
<!-- O 시맨틱 태그 사용 — 문서 구조가 명확 -->
<header>
<nav>
<ul>
<li><a href="/">홈</a></li>
<li><a href="/products">상품</a></li>
</ul>
</nav>
</header>
<main>
<article>
<h1>상품 목록</h1>
<section>...</section>
</article>
</main>
<footer>...</footer>
WAI-ARIA 속성
<!-- 시맨틱 태그만으로 부족한 경우 ARIA 속성으로 보충 -->
<!-- O 모달 다이얼로그 -->
<div role="dialog" aria-modal="true" aria-labelledby="modal-title">
<h2 id="modal-title">주문 확인</h2>
<p>주문을 완료하시겠습니까?</p>
<button>확인</button>
<button>취소</button>
</div>
<!-- O 로딩 상태 알림 -->
<div aria-live="polite" aria-busy="true">
상품 목록을 불러오는 중입니다...
</div>
<!-- O 탭 UI -->
<div role="tablist">
<button role="tab" aria-selected="true" aria-controls="panel-1">상세 정보</button>
<button role="tab" aria-selected="false" aria-controls="panel-2">리뷰</button>
</div>
<div role="tabpanel" id="panel-1">상세 정보 내용</div>
<div role="tabpanel" id="panel-2" hidden>리뷰 내용</div>
웹 접근성 검사 도구
| 도구 | 설명 |
|---|---|
| Lighthouse | Chrome 내장 도구, 접근성 점수 제공 |
| axe DevTools | Chrome 확장, 상세한 접근성 위반 사항 검출 |
| WAVE | 웹 기반 접근성 평가 도구 |
| 스크린 리더 | NVDA(무료), VoiceOver(Mac 내장)로 직접 테스트 |
한국 웹 접근성 관련 법률
[장애인차별금지법]
2008년부터 시행
→ 공공기관, 교육기관 웹사이트는 웹 접근성 준수 의무
→ 2013년부터 민간 기업까지 확대
[한국형 웹 콘텐츠 접근성 지침 KWCAG]
→ WCAG를 기반으로 한국 상황에 맞게 제정
→ 웹 접근성 품질 인증 마크 제도 운영
→ 접근성 미준수 시 차별 행위로 판단될 수 있음
면접 포인트
- 웹 접근성은 단순히 장애인을 위한 것이 아니라, 모든 사용자(고령자, 일시적 장애, 다양한 디바이스 환경)의 사용성을 보장하는 것이며, 법적 의무이기도 합니다.
- 핵심은 시맨틱 HTML을 기본으로 사용하고, 부족한 부분을 WAI-ARIA 속성으로 보완하는 것입니다. ARIA를 남용하지 않고 시맨틱 태그를 우선 사용하는 것이 원칙입니다.
- 프론트엔드 개발자라면 이미지 대체 텍스트, 키보드 접근성, 명도 대비, 시맨틱 마크업은 기본적으로 구현할 수 있어야 하며, Lighthouse 등의 도구로 정기적으로 점검하는 것이 좋습니다.