Contents
see List웹 접근성(A11y) 체크리스트
웹 접근성은 장애인, 고령자 등 모든 사용자가 웹사이트를 동등하게 이용할 수 있도록 하는 것입니다. WCAG 2.1 가이드라인을 기반으로 실무에서 반드시 체크해야 할 항목들을 정리했습니다.
왜 중요한가요?
- 법적 의무 (장애인차별금지법)
- 공공기관, 대기업 필수 준수
- SEO 향상 (스크린리더 = 검색엔진)
- 더 나은 사용자 경험
1. 이미지와 대체 텍스트
<!-- 정보 전달 이미지 -->
<img src="logo.png" alt="소프트모아 로고">
<!-- 장식용 이미지 (빈 alt) -->
<img src="decoration.png" alt="">
<!-- 복잡한 이미지 (차트, 다이어그램) -->
<figure>
<img src="chart.png" alt="2024년 매출 차트">
<figcaption>
2024년 1분기 매출 100억, 2분기 120억...
</figcaption>
</figure>
<!-- 아이콘 버튼 -->
<button aria-label="메뉴 열기">
<svg aria-hidden="true">...</svg>
</button>2. 시맨틱 HTML
<!-- 올바른 구조 -->
<header>
<nav aria-label="메인 메뉴">...</nav>
</header>
<main>
<article>
<h1>제목</h1>
<section aria-labelledby="section1">
<h2 id="section1">섹션 제목</h2>
</section>
</article>
<aside>사이드바</aside>
</main>
<footer>...</footer>
<!-- 버튼은 button으로 -->
<button onclick="submit()">제출</button>
<!-- div로 버튼 X -->3. 키보드 접근성
<!-- 포커스 스타일 유지 -->
<style>
:focus {
outline: 2px solid #005fcc;
outline-offset: 2px;
}
/* outline: none 하지 마세요! */
/* 커스텀 포커스 스타일 사용 */
:focus-visible {
outline: 3px solid #005fcc;
box-shadow: 0 0 0 6px rgba(0,95,204,0.3);
}
</style>
<!-- 스킵 링크 -->
<a href="#main-content" class="skip-link">
본문으로 건너뛰기
</a>
<!-- 탭 순서 -->
<!-- tabindex="0" - 자연스러운 순서 -->
<!-- tabindex="-1" - 프로그래밍으로만 포커스 -->
<!-- tabindex="1+" 사용 금지 -->4. 폼 접근성
<!-- 라벨 연결 필수 -->
<label for="email">이메일</label>
<input type="email" id="email"
aria-describedby="email-hint"
aria-required="true">
<span id="email-hint">예: user@example.com</span>
<!-- 에러 메시지 -->
<input type="email" aria-invalid="true"
aria-describedby="email-error">
<span id="email-error" role="alert">
유효한 이메일을 입력하세요
</span>
<!-- 필수 필드 -->
<label>
이름 <span aria-hidden="true">*</span>
<span class="sr-only">필수</span>
</label>
<input required aria-required="true">5. 색상과 명도 대비
/* 최소 명도 대비 4.5:1 (일반 텍스트) */
/* 대형 텍스트(18px+) 3:1 */
/* 좋은 예 */
color: #333;
background: #fff;
/* 명도 대비: 12.63:1 */
/* 나쁜 예 */
color: #999;
background: #fff;
/* 명도 대비: 2.85:1 (실패) */
/* 색상만으로 정보 전달 금지 */
/* 에러: 빨간색 + 아이콘/텍스트 */
.error {
color: #d32f2f;
border-left: 3px solid #d32f2f;
}
.error::before { content: "⚠ "; }6. 동적 콘텐츠
<!-- 라이브 리전 -->
<div aria-live="polite">
검색 결과 10개를 찾았습니다
</div>
<div aria-live="assertive">
에러: 세션이 만료되었습니다
</div>
<!-- 로딩 상태 -->
<button aria-busy="true" disabled>
<span class="sr-only">저장 중...</span>
<svg aria-hidden="true">...</svg>
</button>7. 모달/다이얼로그
<div role="dialog"
aria-modal="true"
aria-labelledby="dialog-title">
<h2 id="dialog-title">확인</h2>
<p>삭제하시겠습니까?</p>
<button>취소</button>
<button>확인</button>
</div>
<!-- 포커스 트랩 필수 -->
<!-- ESC로 닫기 -->
<!-- 닫을 때 원래 위치로 포커스 -->접근성 도구 스타일
/* 스크린리더 전용 텍스트 */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
border: 0;
}테스트 도구
- Chrome DevTools Lighthouse
- axe DevTools 확장
- WAVE 접근성 평가 도구
- NVDA/VoiceOver 스크린리더 테스트