웹 접근성(Accessibility, A11y)은 장애가 있는 사람을 포함한 모든 사용자가 웹을 이용할 수 있도록 보장하는 것입니다. 시각 장애인의 스크린 리더, 지체 장애인의 키보드 전용 탐색 등 다양한 사용 환경을 고려해야 합니다. 접근성을 지키면 SEO도 함께 좋아집니다.
시맨틱 HTML — 기본 중의 기본
<!-- 나쁜 예 -->
<div class="header">
<div class="nav">
<div onclick="go('/')">홈</div>
</div>
</div>
<!-- 좋은 예 -->
<header>
<nav aria-label="주요 메뉴">
<a href="/">홈</a>
</nav>
</header>
<main>
<article>
<h1>제목</h1>
<p>내용</p>
</article>
</main>
<footer>
<address>contact@mailissue.co.kr</address>
</footer>
이미지 alt 텍스트
<!-- 정보를 전달하는 이미지 -->
<img src="chart.png" alt="2026년 1분기 매출이 전년 대비 23% 상승한 막대 그래프">
<!-- 장식용 이미지 (스크린 리더가 무시) -->
<img src="divider.png" alt="">
<!-- 기능 버튼의 아이콘 -->
<button aria-label="메뉴 닫기">
<img src="close.svg" alt="">
</button>
키보드 접근성
<!-- 클릭 가능한 요소는 button 또는 a 사용 -->
<button onclick="openModal()">모달 열기</button>
<!-- div를 버튼처럼 쓸 때 (최후의 수단) -->
<div
role="button"
tabindex="0"
onclick="openModal()"
onkeydown="if(event.key==='Enter'||event.key===' ')openModal()"
>모달 열기</div>
<!-- 포커스 표시 절대 제거하지 말 것 -->
/* 절대 금지 */
* { outline: none; }
/* 대신 커스텀 포커스 스타일 */
:focus-visible {
outline: 2px solid #6891f8;
outline-offset: 2px;
border-radius: 4px;
}
ARIA 속성 활용
<!-- 모달 -->
<div
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
aria-describedby="modal-desc"
>
<h2 id="modal-title">확인</h2>
<p id="modal-desc">정말 삭제하시겠습니까?</p>
</div>
<!-- 상태 알림 -->
<div role="status" aria-live="polite">
저장되었습니다.
</div>
<!-- 확장/축소 버튼 -->
<button aria-expanded="false" aria-controls="menu">메뉴</button>
<ul id="menu" hidden>...</ul>
색상 대비
WCAG 2.1 기준으로 일반 텍스트는 4.5:1, 큰 텍스트(18px 이상)는 3:1 이상의 명암 대비가 필요합니다.
/* 나쁜 예 — 대비 부족 */
.subtle { color: #aaa; background: #fff; } /* 2.3:1 */
/* 좋은 예 */
.readable { color: #595959; background: #fff; } /* 7:1 */
/* OKLCH로 접근성 있는 색상 선택 */
.text-muted { color: oklch(45% 0.05 240); } /* 충분한 대비 */
폼 접근성
<form>
<div>
<!-- label과 input을 반드시 연결 -->
<label for="email">이메일 <span aria-hidden="true">*</span></label>
<input
type="email"
id="email"
name="email"
required
aria-required="true"
aria-describedby="email-hint email-error"
>
<span id="email-hint">예: hello@example.com</span>
<span id="email-error" role="alert"></span>
</div>
</form>
접근성 자동 검사 도구
개발 단계에서 접근성 문제를 빠르게 발견하기 위한 도구들이 많습니다. 완벽하지는 않지만 명백한 오류를 자동으로 잡아주므로 반드시 활용하세요.
- Lighthouse — Chrome DevTools에 내장. 접근성 점수와 구체적인 문제 목록을 제공합니다.
- axe DevTools — 브라우저 확장 프로그램. 실시간으로 WCAG 위반 사항을 강조 표시해 줍니다.
- WAVE — 웹 기반 접근성 평가 도구. 시각적으로 문제 위치를 표시해 직관적입니다.
- 키보드 직접 탐색 — Tab, Shift+Tab, Enter, Space, 방향키만으로 사이트의 모든 기능을 사용할 수 있는지 직접 확인합니다.
스크린 리더 실제 테스트
자동 검사 도구가 놓치는 문제는 스크린 리더를 직접 사용해야 발견됩니다. 무료로 사용할 수 있는 스크린 리더는 다음과 같습니다.
- NVDA (Windows, 무료) — 가장 많이 사용되는 스크린 리더입니다.
- VoiceOver (macOS·iOS 내장) — Mac/iPhone 사용자라면 바로 켤 수 있습니다. macOS는 Cmd+F5, iOS는 설정 > 손쉬운 사용에서 활성화합니다.
- TalkBack (Android 내장) — Android 기기에서 설정 > 접근성에서 활성화합니다.
접근성의 비즈니스 이점
접근성은 윤리적 의무이기도 하지만, 비즈니스 측면에서도 이점이 있습니다. 전 세계 인구의 약 15%(약 10억 명)가 어떤 형태로든 장애를 가지고 있어, 접근성을 개선하면 더 넓은 사용자 층에 도달할 수 있습니다. 또한 시맨틱 HTML과 ARIA 속성은 검색 엔진 크롤러가 콘텐츠를 더 잘 이해하도록 도와주기 때문에 SEO 점수도 함께 올라가는 경우가 많습니다. 많은 국가에서 공공 웹사이트와 일부 상업 사이트에 접근성 기준 준수를 법으로 요구하고 있으므로, 법적 리스크를 줄이는 역할도 합니다.
✅ 모든 이미지에 적절한 alt 텍스트
✅ 키보드만으로 전체 사이트 탐색 가능
✅ 포커스 표시 스타일 명확히
✅ 색상만으로 정보 전달 금지
✅ 폼 요소에 label 연결
✅ 명암 대비 4.5:1 이상 확인
✅ Lighthouse·axe로 자동 검사 통과
✅ 스크린 리더로 주요 흐름 직접 테스트
ARIA Live Regions — 동적 콘텐츠 알림
페이지 이동 없이 콘텐츠가 동적으로 변경될 때(로딩 완료, 에러 메시지, 폼 검증 결과 등), 스크린 리더 사용자에게는 변경 사실이 전달되지 않습니다. aria-live로 이를 해결하세요.
<!-- 알림 영역 — 변경 시 스크린 리더가 자동으로 읽어줌 -->
<div aria-live="polite" aria-atomic="true" id="status-message"></div>
<!-- 긴급 알림 (현재 읽던 것을 멈추고 즉시 읽음) -->
<div role="alert" id="error-message"></div>
// 동적으로 내용 변경 → 스크린 리더가 자동으로 읽어줌
document.getElementById('status-message').textContent = '파일 업로드가 완료되었습니다.';
document.getElementById('error-message').textContent = '서버 오류가 발생했습니다.';
aria-live="polite"는 현재 읽던 내용이 끝난 후 변경된 내용을 읽습니다. role="alert"(aria-live="assertive"와 동일)는 즉시 끼어들어 읽습니다. 에러 메시지처럼 즉각적인 알림이 필요한 경우에만 assertive를 사용하고, 대부분은 polite가 적합합니다.
prefers-reduced-motion — 모션 감소 설정
전정기관 장애가 있는 사용자는 애니메이션에 불편함을 느낄 수 있습니다. OS의 "모션 줄이기" 설정을 존중하는 CSS를 작성하세요.
/* 기본 애니메이션 */
.card {
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-4px);
}
/* 모션 감소 설정 시 애니메이션 비활성화 */
@media (prefers-reduced-motion: reduce) {
.card {
transition: none;
}
.card:hover {
transform: none;
}
/* 또는 전체 애니메이션 일괄 비활성화 */
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
접근성 자동화 테스트 도입
수동 테스트만으로는 모든 접근성 문제를 발견하기 어렵습니다. CI/CD에 자동화 테스트를 통합하면 회귀를 방지할 수 있습니다.
// Jest + jest-axe로 단위 테스트에 접근성 검사 추가
import { render } from '@testing-library/react';
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
test('LoginForm has no accessibility violations', async () => {
const { container } = render(<LoginForm />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
자동화 테스트는 WCAG 위반의 약 30~40%만 감지합니다. 자동화 + 키보드 테스트 + 스크린 리더 테스트를 조합해야 더 폭넓은 접근성을 보장할 수 있습니다.
접근성이 비즈니스에 중요한 이유
웹 접근성을 순수한 도덕적 의무나 법적 요건으로만 생각하면 개발팀에서 우선순위를 높이기 어렵습니다. 비즈니스 관점에서 접근성의 가치를 이해하면 팀의 공감대를 얻기 훨씬 쉬워집니다. 전 세계 인구의 약 15%가 어떤 형태로든 장애를 가지고 있습니다. 한국만 해도 250만 명 이상의 등록 장애인이 있고, 비등록 장애인과 일시적 장애(골절, 안과 수술 등)를 포함하면 훨씬 많습니다. 이 사용자들이 여러분의 서비스를 이용할 수 없다면, 그만큼의 잠재 고객을 놓치는 것입니다. 접근성을 개선하면 이 사용자층이 서비스에 진입할 수 있게 됩니다.
SEO와의 시너지도 큽니다. 스크린 리더가 잘 읽을 수 있는 시맨틱 HTML, 이미지 alt 텍스트, 명확한 제목 구조는 검색 엔진 크롤러가 좋아하는 요소와 정확히 겹칩니다. 접근성 기준을 따르면 SEO도 자연스럽게 개선됩니다. 법적 리스크 관리 측면도 있습니다. 미국의 ADA(Americans with Disabilities Act)를 비롯한 여러 나라의 법률이 디지털 서비스에도 접근성 요건을 적용하고 있으며, 국내에서도 장애인차별금지법에 따라 공공기관 웹사이트의 접근성 준수가 의무화되어 있습니다. 민간 기업으로 규제가 확대되는 추세이므로, 미리 접근성을 갖추는 것이 훨씬 경제적입니다.