ARIA 접근성 가이드

역할 · 복합 위젯

role="grid"

행과 열로 이루어지고, 방향키로 셀 사이를 이동하며 선택·편집할 수 있는 상호작용 표입니다.

심화

한눈에 보기

분류
복합 위젯
대응 HTML
없음 (<table>에 role="grid"를 붙여 만들 수 있음)
이름 정하는 방법
작성자
이름 필수
예
필수 상위 요소
없음
필수 하위 요소
row rowgroup

설명

grid는 table의 구조(행·열·제목 셀)에 위젯 동작을 더한 역할입니다. 그리드 전체가 탭 순서에서 한 번만 멈추고, 안에서는 방향키로 gridcell 사이를 이동합니다. 필수 하위 요소는 row(직접 또는 rowgroup 안)입니다.

APG는 두 가지 용도를 구분합니다.

  • 데이터 그리드 — 스프레드시트, 정렬·선택·편집이 되는 데이터 목록. 제목 셀(columnheader, rowheader)이 있습니다.
  • 레이아웃 그리드 — 달력 날짜, 사진 목록, 태그 목록처럼 여러 상호작용 요소를 2차원으로 묶어 탭 정지를 줄이는 용도. 제목 셀이 없을 수 있습니다.

그리드 속성: 일부 행·열만 렌더링하면 aria-rowcount·aria-colcount로 전체 크기를, 여러 셀을 고를 수 있으면 aria-multiselectable, 전체가 편집 불가면 aria-readonly를 씁니다. 포커스 관리는 로빙 tabindex 또는 aria-activedescendant 중 하나를 고릅니다.

읽기만 하는 표를 grid로 만들지 마세요

화면낭독기는 grid에 들어가면 포커스(애플리케이션) 모드로 전환해, 표 읽기 단축키 대신 웹 페이지의 키 처리를 따릅니다. 셀 단위 조작이 없는 표를 grid로 만들면 오히려 읽기 어려워집니다. 정렬 버튼 정도만 있는 표는 일반 <table> + 제목 셀 안의 <button>과 aria-sort로 충분합니다.

테스터 관점

  • Tab 한 번으로 그리드에 들어가고 한 번 더 누르면 나가는지, 다시 들어오면 마지막 셀로 돌아오는지 확인합니다.
  • 셀 이동 시 열 제목이 함께 읽히는지 확인합니다.
  • 셀 안 위젯(버튼, 입력란)이 있다면 Enter/F2로 들어가고 Esc로 셀 탐색으로 돌아오는지 확인합니다.

함께 쓰는 속성

지원 속성

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

키보드 동작

키보드 동작
키동작
→오른쪽 셀로 이동합니다. 행 끝이면 움직이지 않습니다(레이아웃 그리드는 다음 행 첫 셀로 넘어갈 수 있음).
←왼쪽 셀로 이동합니다.
↓아래 셀로 이동합니다.
↑위 셀로 이동합니다.
Page Down(선택 사항) 정해진 행 수만큼 아래로 이동합니다.
Page Up(선택 사항) 정해진 행 수만큼 위로 이동합니다.
Home현재 행의 첫 셀로 이동합니다.
End현재 행의 마지막 셀로 이동합니다.
Ctrl + Home첫 행의 첫 셀로 이동합니다.
Ctrl + End마지막 행의 마지막 셀로 이동합니다.
Ctrl + Space(선택 지원 시) 현재 셀이 속한 열을 선택합니다.
Shift + Space(선택 지원 시) 현재 셀이 속한 행을 선택합니다.
Ctrl + A(선택 지원 시) 모든 셀을 선택합니다.
Shift + →(선택 지원 시) 선택 범위를 오른쪽으로 넓힙니다. 다른 방향키도 같습니다.
Enter(셀 안 위젯) 편집 모드로 들어가거나 셀의 위젯을 실행합니다. F2도 지원할 수 있습니다.
Esc(편집 모드) 편집을 취소하고 셀 탐색으로 돌아갑니다.

사용 예

table 기반 데이터 그리드

HTML
<table role="grid" aria-labelledby="g-cap" aria-readonly="true">
  <caption id="g-cap">이번 주 근무표</caption>
  <tr><th scope="col">이름</th><th scope="col">월</th><th scope="col">화</th></tr>
  <tr><th scope="row">김민지</th><td tabindex="0">주간</td><td tabindex="-1">야간</td></tr>
</table>

가상 스크롤 그리드

HTML
<div role="grid" aria-label="주문 목록" aria-rowcount="5000" aria-colcount="6">
  <div role="rowgroup">
    <div role="row" aria-rowindex="1">
      <div role="columnheader" aria-colindex="1">주문 번호</div> ...
    </div>
  </div>
  <div role="rowgroup">
    <div role="row" aria-rowindex="1201"> ... </div>
  </div>
</div>

셀 이동 (로빙 tabindex)

JavaScript
function focusCell(r, c) {
  var cell = rows[r].cells[c];
  current.tabIndex = -1;
  cell.tabIndex = 0;
  cell.focus();
  current = cell;
}

일반 데이터 표를 grid로 바꾸는 실수

비권장비권장
<table role="grid">   <!-- 클릭·편집 없는 단순 표 -->
  <tr><th>상품</th><th>가격</th></tr>
  <tr><td>사과</td><td>3,000원</td></tr>
</table>

직접 해 보기

그리드 안 셀에 포커스를 두고 방향키, Home/End, Ctrl+Home/End로 이동해 보세요. Tab을 누르면 그리드를 벗어나고, 다시 들어오면 마지막으로 있던 셀로 돌아옵니다. Space로 셀을 선택/해제합니다.

근무표 (선택한 칸: 휴무 신청)
이름월화수
김민지주간야간주간
이서준야간주간휴무
박하은주간휴무야간

화면낭독기에서는

화면낭독기 안내 예시 (표현은 화면낭독기·브라우저·버전에 따라 조금씩 다릅니다)
상황들리는 안내 (예)
그리드로 처음 이동근무표 (선택한 칸: 휴무 신청), 표, 4열 4행, 월, 김민지, 주간, 선택 안 됨
→로 이동화, 야간
Space로 선택선택됨

사용 지침

이렇게 쓰세요

  • 셀 단위 탐색·선택·편집이 실제로 필요할 때만 씁니다.
  • 그리드 전체를 탭 정지 하나로 만들고, 현재 셀 위치를 기억합니다.
  • 열 제목·행 제목을 제공하고, 일부만 렌더링하면 aria-rowcount/aria-rowindex를 넣습니다.

이렇게 쓰지 마세요

  • 읽기 전용 표에 쓰지 않습니다.
  • row를 빼고 셀을 그리드에 바로 넣지 않습니다.
  • 셀 안 입력란이 방향키를 가로채 빠져나올 수 없게 만들지 않습니다. Esc 등 탈출 방법을 둡니다.

이 역할을 쓰는 패턴

참고 자료