ARIA 접근성 가이드

기본 개념

역할·상태·속성

ARIA의 세 가지 구성 요소인 역할(role), 상태(state), 속성(property)의 차이와, WAI-ARIA 1.2의 역할 분류 체계, 모든 요소에 쓸 수 있는 전역 속성을 정리합니다.

세 가지 구성 요소

세 가지 구성 요소
구분뜻바뀌는 빈도쓰는 법예
역할 (Role)요소가 무엇인지거의 바뀌지 않음role="..."tab, dialog, navigation
속성 (Property)요소의 성질·관계잘 바뀌지 않음aria-*aria-labelledby, aria-controls, aria-required
상태 (State)요소의 지금 상황사용자 조작에 따라 자주 바뀜aria-*aria-expanded, aria-checked, aria-selected
역할·상태·속성이 함께 쓰인 메뉴 버튼
<button type="button" aria-haspopup="menu" aria-controls="user-menu" aria-expanded="false">
  내 계정
</button>
<ul id="user-menu" role="menu" hidden>
  <li role="menuitem">로그아웃</li>
</ul>
  • menu, menuitem — 역할: 메뉴와 메뉴 항목입니다.
  • aria-haspopup — 속성: 메뉴를 여는 버튼이라는 성질입니다.
  • aria-controls — 속성: 제어 대상과의 관계입니다.
  • aria-expanded — 상태: 지금 메뉴가 닫혀 있음을 알립니다. 메뉴를 열면 true로 바뀝니다.

상태와 속성의 경계

명세는 상태와 속성을 구분하지만, 문법과 동작은 같습니다. 둘 다 aria-로 시작하고 값이 바뀌면 브라우저가 접근성 트리를 갱신합니다. 명세 스스로도 “상태와 속성의 차이는 미묘하다”고 설명합니다. 이 사이트의 속성 레퍼런스는 각 항목에 상태/속성 구분을 표시합니다.

역할 지정의 기본 규칙

  • 역할은 하나만 유효합니다. role="switch checkbox"처럼 공백으로 여러 개를 쓰면 브라우저는 앞에서부터 처음으로 인식하는 역할 하나를 씁니다(대체 역할). 일반적으로는 하나만 씁니다.
  • 추상 역할은 쓸 수 없습니다. widget, landmark, input 같은 추상 역할은 분류용이며, 작성자가 지정하면 안 됩니다.
  • 역할을 바꾸지 않습니다. 상황에 따라 role 값을 바꾸는 대신 다른 요소로 교체합니다.
  • 일부 역할은 필수 속성이 있습니다. 예: checkbox는 aria-checked, heading은 aria-level, slider는 aria-valuenow.
  • 일부 역할은 필수 상위·하위 역할이 있습니다. 예: tab은 tablist 안에, option은 listbox 안에 있어야 합니다.
비권장tablist 안에 관계없는 요소가 섞임
<div role="tablist">
  <div role="presentation">
    <div role="tab" aria-selected="true">공지</div>
  </div>
  <a role="tab" href="#p2">자료실</a>
  <span>|</span>
</div>
권장tablist의 자식은 tab만
<div role="tablist" aria-label="게시판">
  <button role="tab" aria-selected="true" id="t1" aria-controls="p1">공지</button>
  <button role="tab" aria-selected="false" id="t2" aria-controls="p2" tabindex="-1">자료실</button>
</div>

역할 분류 체계

WAI-ARIA 1.2는 역할을 상속 관계를 가진 분류(taxonomy)로 정리합니다. 작성자가 쓸 수 있는 구체 역할은 다음 여섯 분류로 나뉘며, 이를 묶는 상위 개념으로 추상 역할이 있습니다.

역할 분류 체계
분류설명역할
추상 역할
Abstract
분류 체계를 만들기 위한 개념상의 역할입니다. 작성자가 쓰면 안 됩니다.command composite input landmark range roletype section sectionhead select structure widget window
위젯
Widget
사용자가 직접 조작하는 단일 요소입니다.button checkbox gridcell link menuitem menuitemcheckbox menuitemradio option progressbar radio scrollbar searchbox separator slider spinbutton switch tab tabpanel textbox treeitem
복합 위젯
Composite
여러 하위 위젯을 담고, 보통 하나의 Tab 정지점 안에서 화살표 키로 이동하는 위젯입니다.combobox grid listbox menu menubar radiogroup tablist tree treegrid
문서 구조
Document Structure
콘텐츠의 짜임새를 나타냅니다. 대부분 조작하지 않습니다.application article blockquote caption cell code columnheader definition deletion document emphasis feed figure generic group heading img insertion list listitem math meter none note paragraph presentation row rowgroup rowheader strong subscript superscript table term time toolbar tooltip
랜드마크
Landmark
페이지의 큰 영역입니다. 화면낭독기 사용자는 랜드마크 단위로 이동합니다.banner complementary contentinfo form main navigation region search
라이브 리전
Live Region
내용이 바뀌면 포커스와 관계없이 알려지는 영역입니다.alert log marquee status timer
창
Window
본문 위에 따로 뜨는 창입니다.alertdialog dialog

separator는 포커스를 받을 수 있을 때(분할 막대처럼 값을 조절할 때)는 위젯, 그렇지 않을 때는 문서 구조 역할로 동작합니다. directory 역할은 ARIA 1.2에서 사용 중단되었으며 list를 대신 씁니다.

역할을 상속으로 이해하기

예를 들어 checkbox는 input을, switch는 checkbox를 상속합니다. 그래서 switch도 aria-checked를 필수로 가집니다. 각 역할 문서의 “필수 속성”과 “지원 속성”은 이 상속 관계에서 나옵니다. 전체 목록은 역할 레퍼런스에서 확인하세요.

상태와 속성의 분류

WAI-ARIA 1.2는 상태와 속성을 쓰임새에 따라 네 가지로 나눕니다. 이 사이트의 속성 레퍼런스는 이를 조금 더 세분해 정리했습니다.

상태와 속성의 분류
분류설명예
위젯 속성사용자 입력을 받는 요소의 상태·성질aria-autocomplete aria-checked aria-disabled aria-expanded aria-haspopup aria-invalid aria-pressed aria-readonly aria-required aria-selected aria-valuenow
라이브 리전 속성동적 변경을 어떻게 알릴지aria-live aria-atomic aria-relevant aria-busy
드래그 앤 드롭 속성ARIA 1.1부터 사용 중단aria-grabbed aria-dropeffect
관계 속성요소와 요소 사이의 연결, 구조 정보aria-activedescendant aria-controls aria-describedby aria-labelledby aria-owns aria-posinset aria-setsize aria-colindex aria-rowindex

전역 속성

전역 속성(global states and properties)은 역할과 관계없이 모든 HTML 요소에 쓸 수 있는 ARIA 속성입니다. 단, generic, presentation처럼 이름을 가질 수 없는 역할에서는 aria-label과 aria-labelledby를 쓰면 안 되는 등 예외가 있습니다.

1.2에서 전역 지위를 잃은 속성

aria-disabled aria-errormessage aria-haspopup aria-invalid는 ARIA 1.1까지 전역 속성이었지만, 1.2에서는 전역으로 쓰는 것이 사용 중단되었습니다. 이제는 해당 속성을 지원하는 역할(예: button, textbox, combobox)에만 씁니다.

WAI-ARIA 1.3 초안에는 aria-description, aria-braillelabel, aria-brailleroledescription가 전역 속성으로 추가되어 있습니다.

값의 형식

ARIA 속성 값은 모두 문자열이지만, 명세는 값의 형식을 정해 둡니다.

값의 형식
형식설명예
true/false참 또는 거짓aria-hidden="true"
true/false/undefined값이 없으면 해당 없음aria-expanded
tristatetrue, false, mixed(일부 선택)aria-checked="mixed"
ID 참조 / ID 참조 목록다른 요소의 id, 공백으로 여러 개aria-labelledby="title sub"
정수 / 숫자정수나 실수aria-level="2", aria-valuenow="3.5"
문자열자유 텍스트aria-label="닫기"
토큰 / 토큰 목록정해진 값 중 하나(또는 여러 개)aria-live="polite", aria-relevant="additions text"
비권장형식에 맞지 않는 값
<button aria-pressed="yes">굵게</button>
<div role="checkbox" aria-checked>동의</div>
권장명세에 정한 값
<button aria-pressed="true">굵게</button>
<div role="checkbox" aria-checked="false" tabindex="0">동의</div>

빈 값과 잘못된 값

잘못된 토큰 값은 대부분 기본값으로 처리되거나 무시됩니다. 예를 들어 aria-pressed="yes"는 브라우저가 이해하지 못해 토글 버튼으로 인식되지 않을 수 있습니다. 검사 도구(axe 등)는 이런 값을 오류로 표시합니다.