역할 · 복합 위젯
role="treegrid"
행을 펼치고 접을 수 있는 그리드입니다. 트리처럼 계층이 있고, 그리드처럼 열이 있습니다.
심화
한눈에 보기
- 분류
- 복합 위젯
- 대응 HTML
- 없음
- 이름 정하는 방법
- 작성자
- 이름 필수
- 예
- 필수 상위 요소
- 없음
설명
treegrid는 grid와 tree를 합친 역할입니다. 메일 스레드 목록, 하위 작업이 있는 작업 표, 폴더 크기·수정일이 함께 보이는 파일 목록처럼 계층이 있는 표에 씁니다. 필수 하위 요소는 row(직접 또는 rowgroup 안)입니다.
계층 정보는 행에 붙입니다.
aria-level— 행의 수준(1부터).aria-expanded— 하위 행이 있는 행만. 하위 행이 없는 행에는 붙이지 않습니다.aria-posinset·aria-setsize— 같은 수준 형제 중 위치와 개수.
표는 DOM상 평평하기 때문에 이 값들을 직접 넣어야 합니다. 접힌 행의 하위 행은 hidden으로 숨깁니다. APG는 포커스가 행에도, 셀에도 갈 수 있는 구조를 제시합니다. 행에 포커스가 있으면 →/←가 펼치기·접기를, 셀에 포커스가 있으면 셀 이동을 합니다.
구현 난도가 높은 패턴입니다
트리그리드는 화면낭독기 지원 편차가 크고, 행·셀 포커스 전환 규칙이 복잡합니다. 계층이 한두 단계이고 열이 단순하다면 일반 표 + 펼침 버튼(디스클로저)이나 트리로 충분한지 먼저 검토합니다.
테스터 관점
- 행으로 이동할 때 수준·펼침 상태·위치가 읽히는지 확인합니다.
- 셀로 이동했을 때 열 제목이 함께 읽히는지 확인합니다.
- 접힌 행 아래 하위 행이 숨김 처리되어 있는지 확인합니다.
함께 쓰는 속성
지원 속성
aria-activedescendantaria-colcountaria-disabledaria-errormessagearia-invalidaria-multiselectablearia-orientationaria-readonlyaria-requiredaria-rowcount전역 속성(이름·설명 등)은 모든 역할에 쓸 수 있어 생략했습니다.
키보드 동작
| 키 | 동작 |
|---|---|
| → | 행 포커스: 접힌 행은 펼치고, 펼쳐졌거나 하위 행이 없으면 행의 첫 셀로 이동합니다. 셀 포커스: 오른쪽 셀로 이동합니다(마지막 셀이면 그대로). |
| ← | 행 포커스: 펼쳐진 행은 접고, 접힌 행은 부모 행으로 이동합니다. 셀 포커스: 왼쪽 셀로 이동하고, 첫 셀이면 (행 포커스를 지원할 때) 행으로 이동합니다. |
| ↓ | 행 포커스: 다음 보이는 행으로. 셀 포커스: 아래 행의 같은 열 셀로 이동합니다. |
| ↑ | 행 포커스: 이전 보이는 행으로. 셀 포커스: 위 행의 같은 열 셀로 이동합니다. |
| Home | 행 포커스: 첫 행으로. 셀 포커스: 현재 행의 첫 셀로 이동합니다. |
| End | 행 포커스: 마지막 보이는 행으로. 셀 포커스: 현재 행의 마지막 셀로 이동합니다. |
| Ctrl + Home | 행 포커스: 첫 행으로. 셀 포커스: 첫 행의 같은 열 셀로 이동합니다. |
| Ctrl + End | 행 포커스: 마지막 행으로. 셀 포커스: 마지막 행의 같은 열 셀로 이동합니다. |
| Enter | 포커스된 행이나 셀의 기본 동작을 실행합니다(예: 메일 열기). 하위 행이 있는 행에서 펼치기/접기로 쓰기도 합니다. |
| Page Down | (선택 사항) 정해진 행 수만큼 아래로 이동합니다. Page Up은 위로 이동합니다. |
| Shift + ↓ | (다중 선택, 선택 사항) 선택 범위를 다음 행으로 넓힙니다. |
| Ctrl + A | (다중 선택, 선택 사항) 모든 행(셀)을 선택합니다. |
사용 예
표 기반 트리그리드
<table role="treegrid" aria-label="받은 메일">
<thead><tr><th scope="col">제목</th><th scope="col">보낸 사람</th></tr></thead>
<tbody>
<tr aria-level="1" aria-posinset="1" aria-setsize="1" aria-expanded="true" tabindex="0">
<td>회의 일정</td><td>김민지</td>
</tr>
<tr aria-level="2" aria-posinset="1" aria-setsize="1" tabindex="-1">
<td>Re: 회의 일정</td><td>이서준</td>
</tr>
</tbody>
</table>행 펼치기
function setExpanded(row, open) {
row.setAttribute('aria-expanded', String(open));
childRowsOf(row).forEach(function (r) { r.hidden = !open; });
}평평한 표에 수준 정보 누락
<table role="treegrid">
<tr class="parent open"><td>회의 일정</td></tr>
<tr class="child"><td>Re: 회의 일정</td></tr> <!-- aria-level, aria-expanded 없음 -->
</table>직접 해 보기
행에 포커스를 두고 ↑ ↓로 이동, →로 펼치거나(이미 펼쳐졌으면) 첫 셀로, ←로 접거나 부모 행으로 이동합니다. 셀에 있을 때는 ← →로 셀 사이를, 첫 셀에서 ←를 누르면 행으로 돌아갑니다. Enter는 메일을 엽니다.
| 제목 | 보낸 사람 | 날짜 |
|---|---|---|
| 회의 일정 안내 | 김민지 | 10/20 |
| Re: 회의 일정 안내 | 이서준 | 10/20 |
| Re: 회의 일정 안내 | 박하은 | 10/21 |
| 보고서 검토 요청 | 최도윤 | 10/21 |
| Re: 보고서 검토 요청 | 김민지 | 10/22 |
| 주간 소식지 | 운영팀 | 10/22 |
실시간 코드 — 조작하면 속성 값이 바뀌는 모습을 볼 수 있습니다
화면낭독기에서는
| 상황 | 들리는 안내 (예) |
|---|---|
| 트리그리드 행으로 이동 | 회의 일정 안내 김민지 10/20, 행, 확장됨, 1/3, 수준 1 |
| →로 셀 이동 | 제목, 회의 일정 안내 |
| 하위 행으로 이동 | Re: 회의 일정 안내 이서준 10/20, 1/2, 수준 2 |
사용 지침
이렇게 쓰세요
- 행에
aria-level,aria-posinset,aria-setsize를 넣고, 하위 행이 있는 행에만aria-expanded를 붙입니다. - 접힌 하위 행은
hidden으로 숨깁니다. - 열 제목을 제공해 셀 맥락이 읽히게 합니다.
이렇게 쓰지 마세요
- 계층이 없는 표에 쓰지 않습니다. 셀 조작만 필요하면
grid, 읽기만 하면table입니다. - 모든 행·셀을 탭 순서에 넣지 않습니다.
관련 역할·패턴
이 역할을 쓰는 패턴