ARIA 접근성 가이드

역할 · 위젯

role="treeitem"

트리(tree) 안의 항목입니다. 하위 항목이 있으면 펼치고 접을 수 있습니다.

심화

한눈에 보기

분류
위젯
대응 HTML
없음
이름 정하는 방법
콘텐츠, 작성자
이름 필수
예
필수 상위 요소
tree group
필수 하위 요소
없음

설명

treeitem은 tree의 항목입니다. 하위 항목이 있는 항목(부모 노드)은 aria-expanded로 펼침 상태를 알리고, 하위 항목들은 role="group"으로 감싸 부모 항목 안에 둡니다. 하위 항목이 없는 항목(끝 노드)에는 aria-expanded를 붙이지 않습니다.

  • 위치 정보 — DOM이 중첩 구조(tree › treeitem › group › treeitem)라면 브라우저가 수준·위치를 계산합니다. 평평한 DOM이나 일부만 불러오는 트리는 aria-level, aria-posinset, aria-setsize를 직접 넣습니다.
  • 선택 — 선택 가능한 트리는 aria-selected를 씁니다. 여러 개를 고를 수 있으면 트리에 aria-multiselectable="true"를 주고, 선택 가능한 모든 항목에 true/false를 명시합니다. 체크박스형 선택이 필요하면 aria-checked(혼합 상태 포함)를 쓸 수 있지만 한 트리에서 두 방식을 섞지 않습니다.

aria-selected의 필수 여부

WAI-ARIA 1.2 표에서는 treeitem이 option을 상속하면서 aria-selected가 “필수”로 함께 상속된 것처럼 표시됩니다. 그러나 APG 트리 뷰 패턴은 선택 기능이 없는 트리나 단일 선택 트리에서 선택되지 않은 항목에 aria-selected를 생략하는 방식을 허용합니다. 선택 기능이 있다면 상태를 명시하는 것이 가장 안전합니다.

항목의 이름은 콘텐츠에서 계산되며, 중첩된 하위 그룹의 텍스트는 보통 부모 항목 이름에 포함되지 않도록 브라우저가 처리합니다. 그래도 이름이 길게 읽히면 라벨 부분을 별도 요소로 두고 aria-labelledby로 지정할 수 있습니다.

테스터 관점

  • 항목마다 “펼쳐짐/접힘”, 수준(레벨), “n개 중 m번째”가 읽히는지 확인합니다.
  • 접힌 항목의 하위 항목이 가상 커서로도 읽히지 않는지(숨김 처리) 확인합니다.
  • →/←가 펼치기·접기·부모 이동을 APG 규칙대로 하는지 확인합니다.

함께 쓰는 속성

지원 속성

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

키보드 동작

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

사용 예

중첩 구조

HTML
<ul role="tree" aria-label="파일">
  <li role="treeitem" aria-expanded="true" aria-selected="false">
    <span>src</span>
    <ul role="group">
      <li role="treeitem" aria-selected="false">index.html</li>
      <li role="treeitem" aria-selected="false">app.js</li>
    </ul>
  </li>
  <li role="treeitem" aria-selected="false">README.md</li>
</ul>

평평한 DOM에서 위치 정보 직접 지정

HTML
<div role="tree" aria-label="조직도">
  <div role="treeitem" aria-level="1" aria-posinset="1" aria-setsize="1" aria-expanded="true">대표</div>
  <div role="treeitem" aria-level="2" aria-posinset="1" aria-setsize="2">개발팀</div>
  <div role="treeitem" aria-level="2" aria-posinset="2" aria-setsize="2">디자인팀</div>
</div>

펼치기·접기

JavaScript
function setExpanded(item, open) {
  if (!item.hasAttribute('aria-expanded')) return;   // 끝 항목
  item.setAttribute('aria-expanded', String(open));
  item.querySelector('[role="group"]').hidden = !open;
}

끝 항목에 aria-expanded를 붙이는 실수

비권장비권장
<li role="treeitem" aria-expanded="false">README.md</li>
<!-- 펼칠 것이 없는데 “접힘”으로 읽혀 사용자가 계속 펼치려 합니다 -->

직접 해 보기

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

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

화면낭독기에서는

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

사용 지침

이렇게 쓰세요

  • tree 안에 직접 넣거나, 부모 항목 안의 group에 넣습니다.
  • 부모 항목에만 aria-expanded를 붙이고, 접히면 하위 그룹을 숨깁니다.
  • 로빙 tabindex로 트리 전체가 탭 정지 하나가 되게 합니다.

이렇게 쓰지 마세요

  • 끝 항목에 aria-expanded를 붙이지 않습니다.
  • 사이트 내비게이션 링크 목록을 트리로 만들지 않습니다. 대부분 디스클로저 내비게이션이 더 알맞습니다.
  • 한 트리에서 aria-selected와 aria-checked를 섞어 쓰지 않습니다.

참고 자료