WAI-ARIA Reference
WAI-ARIA 역할, 상태, 속성 레퍼런스
WAI-ARIA Reference 소개
WAI-ARIA 레퍼런스는 웹 접근성 이니셔티브 접근 가능한 리치 인터넷 애플리케이션(WAI-ARIA) 명세를 4개 카테고리로 정리한 검색 가능한 치트 시트입니다. 위젯(alert, button, checkbox, dialog, grid, link, menu/menuitem, progressbar, radio, slider, tab/tabpanel, textbox, tooltip 등 13개 인터랙티브 역할), 구조(heading/aria-level, list/listitem, tree/treeitem), 랜드마크(banner, navigation, main, search, complementary), 상태/속성(aria-checked, aria-disabled, aria-expanded, aria-hidden, aria-label, aria-live, aria-selected, aria-required)을 모두 다룹니다.
이 레퍼런스는 포용적인 웹 애플리케이션을 만드는 프론트엔드 개발자, UX 엔지니어, 접근성 전문가를 위해 설계되었습니다. ARIA 속성은 네이티브 HTML 의미가 부족할 때 필수적입니다. 예를 들어 커스텀 div 기반 드롭다운에는 role="combobox"와 aria-expanded가 필요하고, SPA에서 동적 콘텐츠 업데이트를 스크린 리더 사용자에게 알리려면 role="alert"와 aria-live="polite"가 필요합니다.
WAI-ARIA 준수는 많은 국가에서 법적으로 요구되는 WCAG 2.1 Level AA 접근성 기준에 필요하며, NVDA, JAWS, VoiceOver 같은 보조 기술 사용자에게 필수적입니다. 4개 카테고리는 ARIA 명세 구조를 반영합니다: 인터랙티브 컴포넌트는 위젯 역할, 페이지 영역은 랜드마크 역할, 문서 구조는 구조적 역할, 현재 상태는 ARIA 속성을 사용합니다. 브라우저 기반으로 무료이며 다크 모드를 지원합니다.
주요 기능
- 위젯 역할: alert(자동 읽기), button, checkbox, dialog(aria-modal 모달), grid, link, menu/menuitem, progressbar, radio, slider, tab/tabpanel/tablist, textbox, tooltip
- 랜드마크 역할: banner(페이지 헤더), navigation(aria-label 포함), main(주요 콘텐츠), search(검색 영역), complementary(부가 콘텐츠)
- 구조 역할: 필수 aria-level이 있는 heading, 커스텀 목록의 list/listitem, 계층 구조의 tree/treeitem
- ARIA 상태: aria-checked(true/false/mixed), aria-disabled, aria-expanded, aria-hidden(장식 요소), aria-selected
- ARIA 속성: aria-label(직접 레이블), aria-live(동적 업데이트의 polite/assertive), aria-required(폼 필드)
- 역할 + 상태 조합: role="tab"과 aria-selected, role="button"과 aria-expanded/aria-controls 등
- 비인터랙티브 요소의 키보드 네비게이션을 위한 적절한 tabindex 사용 HTML 예제
- 라이브 리전 패턴: 검색 결과를 위한 aria-live="polite", 에러 메시지와 상태 업데이트를 위한 role="alert"
자주 묻는 질문
WAI-ARIA란 무엇이며 언제 사용해야 하나요?
WAI-ARIA는 네이티브 접근성 의미가 부족한 HTML 요소에 시맨틱 속성을 제공하는 W3C 명세입니다. 캐러셀, 날짜 선택기, 커스텀 드롭다운처럼 <button>, <select>, <input> 같은 네이티브 HTML 요소로 구현할 수 없는 커스텀 인터랙티브 위젯을 만들 때 사용합니다. ARIA의 첫 번째 규칙: 올바른 의미를 가진 네이티브 HTML 요소를 사용할 수 있다면 그것을 사용하세요.
aria-label과 가시적 레이블의 차이는 무엇인가요?
가시적 레이블(<label for="..."> 또는 입력을 감싸는 방식)이 권장 방법으로, 모든 사용자에게 보이고 스크린 리더가 자동으로 읽습니다. aria-label은 아이콘 버튼처럼 가시적 레이블이 불가능하거나 바람직하지 않을 때 사용합니다. aria-label 값은 요소의 접근 가능한 이름을 완전히 대체하므로, 기존 가시적 텍스트를 참조하려면 aria-labelledby를 사용하세요.
role="alert"와 aria-live="polite"는 언제 각각 사용하나요?
role="alert"(aria-live="assertive"와 동일)는 사용자를 즉시 방해하고 바로 읽어줍니다. 즉각적인 주의가 필요한 중요한 오류와 경고에 사용하세요. aria-live="polite"는 사용자가 현재 작업을 마칠 때까지 기다린 후 읽어줍니다. 검색 결과 수, 상태 메시지, 중요하지 않은 업데이트에 사용합니다. 두 방법 모두 SPA의 동적으로 삽입된 콘텐츠에 작동합니다.
커스텀 모달 대화상자를 접근성 있게 만드는 방법은?
컨테이너에 role="dialog"와 aria-modal="true"를 적용하고, aria-labelledby로 대화상자 제목 요소를 참조합니다. 대화상자가 열릴 때 내부 첫 번째 포커스 가능한 요소로 포커스를 이동하고 포커스 트랩(Tab/Shift+Tab이 대화상자 내에서만 순환)을 구현합니다. 닫힐 때 트리거한 요소로 포커스를 반환합니다. 닫기 버튼에 aria-label="대화상자 닫기"를 추가합니다.
aria-expanded와 aria-selected의 차이는 무엇인가요?
aria-expanded는 아코디언, 드롭다운, 트리 노드 같은 접을 수 있는 요소가 열려있는지(true) 닫혀있는지(false)를 나타냅니다. aria-controls와 함께 제어되는 영역을 가리킵니다. aria-selected는 탭 목록, 목록 상자, 그리드 같은 다중 항목 위젯에서 현재 선택된 항목을 나타냅니다. 체크 상태와 달리 선택 상태는 토글이 아니라 활성 항목을 표시합니다.
접근성 있는 탭 인터페이스를 구현하는 방법은?
role="tablist"인 div 안에 role="tab"과 aria-selected="true/false"가 있는 버튼을 배치합니다. 각 탭 버튼은 aria-controls로 해당 tabpanel div를 가리켜야 합니다. 활성 탭은 aria-selected="true", 비활성 탭은 aria-selected="false"입니다. 키보드 네비게이션을 구현합니다: 좌/우 화살표로 탭 이동, Home/End로 첫/마지막 탭 이동, Tab으로 활성 tabpanel 진입.
언제 tabindex를 요소에 추가해야 하나요?
tabindex="0"은 비인터랙티브 요소(div, span)를 포커스 가능하게 만들고 자연스러운 탭 순서에 포함시킵니다. 네이티브가 아닌 요소에 role="button", role="checkbox" 등 인터랙티브 ARIA 역할을 부여할 때 필요합니다. tabindex="-1"은 JavaScript로 프로그래매틱하게 포커스할 수 있지만 키보드 Tab 네비게이션으로는 접근 불가합니다. 양수 tabindex 값은 자연스러운 읽기 순서를 방해하므로 피하세요.
aria-hidden은 무엇을 하며 언제 사용해야 하나요?
aria-hidden="true"는 요소와 모든 자식을 접근성 트리에서 제거하여 스크린 리더에 보이지 않게 합니다. 순수 장식용 요소(아이콘 폰트, 배경 이미지, 중복 텍스트), 혼란을 줄 수 있는 UI 요소(레이블이 있는 버튼 옆의 로딩 스피너), 논리적으로 보이지 않는 오프스크린 콘텐츠에 사용합니다. 키보드 포커스를 가지거나 포함하는 요소에는 절대 aria-hidden을 적용하지 마세요.