ARIA 접근성 가이드

역할 · 복합 위젯

role="tree"

하위 항목을 펼치고 접을 수 있는 계층형 목록입니다. 파일 탐색기의 폴더 목록이 대표적입니다.

심화

한눈에 보기

분류
복합 위젯
대응 HTML
없음
이름 정하는 방법
작성자
이름 필수
예
필수 상위 요소
없음
필수 하위 요소
treeitem group

설명

tree는 treeitem을 담는 계층형 선택 위젯입니다. 필수 하위 요소는 treeitem이며, 하위 항목 묶음은 group(그 안에 treeitem)으로 만듭니다. 이름이 필수이고, aria-orientation의 기본값은 세로입니다.

  • 구조 — tree › treeitem › group › treeitem처럼 중첩하면 브라우저가 수준과 위치를 계산합니다. 평평한 DOM이면 항목에 aria-level·aria-posinset·aria-setsize를 넣습니다.
  • 선택 — 여러 개를 고를 수 있으면 aria-multiselectable="true". 단일 선택 트리는 포커스를 따라 선택이 바뀌게 할 수도, Enter로 선택하게 할 수도 있습니다.
  • 포커스 — 트리 전체가 탭 정지 하나입니다. 로빙 tabindex(항목에 직접 포커스) 또는 트리에 포커스를 두고 aria-activedescendant로 현재 항목을 가리킵니다.

내비게이션에는 트리가 거의 필요 없습니다

사이트 사이드바처럼 링크 계층을 보여 주는 곳에 트리를 쓰면, 링크 목록 탐색 대신 트리 전용 키보드 규칙을 배워야 합니다. APG에도 “Navigation Treeview” 예제가 있지만, 대부분의 사이트 내비게이션은 중첩 목록 + 디스클로저 버튼이 더 쉽고 견고합니다. 트리는 파일 탐색기·조직도처럼 계층 탐색과 선택이 핵심인 경우에 씁니다.

테스터 관점

  • 트리 이름, 항목의 수준·위치·펼침 상태가 읽히는지 확인합니다.
  • →/←, Home/End, 글자 키 이동이 APG 규칙대로 동작하는지 확인합니다.
  • 접힌 하위 항목이 숨김 처리되어 가상 커서로도 읽히지 않는지 확인합니다.

함께 쓰는 속성

지원 속성

전역 속성(이름·설명 등)은 모든 역할에 쓸 수 있어 생략했습니다.

키보드 동작

키보드 동작
키동작
↓펼치거나 접지 않고, 보이는 다음 항목으로 이동합니다.
↑보이는 이전 항목으로 이동합니다.
→접힌 부모 항목은 펼치고, 펼쳐진 부모 항목은 첫 하위 항목으로 이동합니다. 끝 항목에서는 아무 일도 하지 않습니다.
←펼쳐진 부모 항목은 접고, 하위 항목은 부모 항목으로 이동합니다. 접힌 최상위 항목에서는 아무 일도 하지 않습니다.
Home첫 항목으로 이동합니다.
End보이는 마지막 항목으로 이동합니다.
Enter항목의 기본 동작(열기·선택)을 실행합니다.
글자 키(권장) 그 글자로 시작하는 다음 보이는 항목으로 이동합니다.
*(선택 사항) 현재 항목과 같은 수준의 형제 항목을 모두 펼칩니다.
Space(다중 선택) 현재 항목의 선택을 바꿉니다.
Shift + ↓(다중 선택, 선택 사항) 다음 항목으로 이동하며 선택을 바꿉니다. Shift+↑는 반대 방향입니다.
Shift + Space(다중 선택, 선택 사항) 마지막으로 선택한 항목부터 현재 항목까지 연속으로 선택합니다.
Ctrl + A(다중 선택, 선택 사항) 모든 항목을 선택합니다.

사용 예

중첩 구조의 트리

HTML
<ul role="tree" aria-label="프로젝트 파일">
  <li role="treeitem" aria-expanded="false" aria-selected="false">
    <span>src</span>
    <ul role="group">
      <li role="treeitem" aria-selected="false">index.html</li>
    </ul>
  </li>
  <li role="treeitem" aria-selected="false">README.md</li>
</ul>

다중 선택 트리

HTML
<ul role="tree" aria-label="공유할 폴더" aria-multiselectable="true">
  <li role="treeitem" aria-selected="true">사진</li>
  <li role="treeitem" aria-selected="false">문서</li>
</ul>

보이는 항목 계산

JavaScript
function visibleItems(tree) {
  return Array.prototype.filter.call(tree.querySelectorAll('[role="treeitem"]'), function (el) {
    var p = el.parentElement.closest('[role="treeitem"]');
    while (p) { if (p.getAttribute('aria-expanded') === 'false') return false; p = p.parentElement.closest('[role="treeitem"]'); }
    return true;
  });
}

group 없이 하위 항목을 나열하는 실수

비권장비권장
<li role="treeitem" aria-expanded="true">src
  <ul>   <!-- role="group"이 없으면 계층(수준)이 전달되지 않습니다 -->
    <li role="treeitem">index.html</li>
  </ul>
</li>

직접 해 보기

트리에 포커스를 두고 ↑ ↓로 이동, →로 펼치거나 첫 하위 항목으로, ←로 접거나 상위 항목으로 이동해 보세요. Enter는 항목을 선택하고, *는 같은 수준의 항목을 모두 펼칩니다. 글자 키를 누르면 그 글자로 시작하는 다음 항목으로 이동합니다.

  • src
    • index.html
    • style.css
  • README.md

화면낭독기에서는

화면낭독기 안내 예시 (표현은 화면낭독기·브라우저·버전에 따라 조금씩 다릅니다)
상황들리는 안내 (예)
트리로 이동프로젝트 파일, 트리 뷰, src, 확장됨, 1/3, 수준 1
←로 접음축소됨
하위 항목으로 이동index.html, 2/3, 수준 2

사용 지침

이렇게 쓰세요

  • 트리에 이름을 붙이고, 하위 항목은 group으로 묶습니다.
  • 트리 전체를 탭 정지 하나로 만들고, 마지막 포커스 위치를 기억합니다.
  • 항목 수가 많으면 글자 키 이동을 지원합니다.

이렇게 쓰지 마세요

  • 단순한 사이트 내비게이션에 쓰지 않습니다.
  • treeitem이 아닌 요소(버튼, 링크)를 트리 항목처럼 섞지 않습니다.
  • 접힌 하위 항목을 화면에서만 감추고 접근성 트리에 남기지 않습니다.

참고 자료