역할 · 위젯
role="gridcell"
그리드(grid)나 트리그리드(treegrid)의 한 칸입니다. 일반 표의 cell과 달리 포커스를 받고 조작할 수 있습니다.
한눈에 보기
- 분류
- 위젯
- 대응 HTML
role="grid"인<table>안의<td>- 이름 정하는 방법
- 콘텐츠, 작성자
- 이름 필수
- 아니요
- 필수 상위 요소
row- 필수 하위 요소
- 없음
설명
gridcell은 grid 또는 treegrid 안의 row에 들어가는 칸입니다. cell과 표 구조 속성(aria-colindex, aria-rowspan 등)은 같지만, 위젯이라는 점이 다릅니다. 방향키로 셀 사이를 이동하고, 선택(aria-selected)하거나, 편집 가능(aria-readonly)하다는 것을 알릴 수 있습니다.
<table role="grid"> 안의 <td>는 브라우저가 자동으로 gridcell로 노출하므로 따로 역할을 붙일 필요가 없습니다. <div>로 그리드를 만들 때만 role="gridcell"을 명시합니다.
포커스는 셀 또는 셀 안의 요소로
APG 그리드 패턴에서는 그리드 전체가 탭 순서에서 한 번만 멈추고, 그 안에서는 방향키로 셀을 오갑니다. 포커스를 받는 대상은 셀 자체이거나, 셀 안에 버튼·링크 같은 요소가 하나뿐이면 그 요소입니다. 이를 위해 로빙 tabindex(현재 셀만 tabindex="0", 나머지는 -1) 또는 그리드의 aria-activedescendant를 씁니다.
단순한 데이터 표에는 grid를 쓰지 않습니다
읽기만 하는 표는 HTML <table>(역할 table/cell)이 맞습니다. 표를 grid로 바꾸면 화면낭독기가 포커스 모드로 전환되어 표 읽기 명령을 쓰기 어려워집니다. 셀 단위 탐색·선택·편집이 실제로 필요할 때만 gridcell을 씁니다.
테스터 관점
- 셀로 이동할 때 열 제목·행 제목과 함께 읽히는지 확인합니다(
columnheader,rowheader연결). - 선택 가능한 그리드라면 선택된 셀에
aria-selected="true"가 붙는지 확인합니다. - 가상화(일부 행만 렌더링)된 그리드는
aria-rowindex/aria-colindex와 그리드의aria-rowcount/aria-colcount가 실제 위치를 알리는지 확인합니다.
함께 쓰는 속성
지원 속성
aria-colindexaria-colspanaria-disabledaria-errormessagearia-expandedaria-haspopuparia-invalidaria-readonlyaria-requiredaria-rowindexaria-rowspanaria-selected전역 속성(이름·설명 등)은 모든 역할에 쓸 수 있어 생략했습니다.
키보드 동작
| 키 | 동작 |
|---|---|
| → | 오른쪽 셀로 포커스를 옮깁니다. 행의 마지막 셀이면 움직이지 않습니다. |
| ← | 왼쪽 셀로 포커스를 옮깁니다. |
| ↓ | 아래 셀로 포커스를 옮깁니다. |
| ↑ | 위 셀로 포커스를 옮깁니다. |
| Home | 현재 행의 첫 셀로 이동합니다. |
| End | 현재 행의 마지막 셀로 이동합니다. |
| Ctrl + Home | 첫 행의 첫 셀로 이동합니다. |
| Ctrl + End | 마지막 행의 마지막 셀로 이동합니다. |
| Page Down | (선택 사항) 여러 행 아래로 이동합니다. |
| Page Up | (선택 사항) 여러 행 위로 이동합니다. |
| Enter | (편집·조작 가능한 셀) 셀 안의 위젯을 조작하거나 편집 모드로 들어갑니다. F2를 함께 지원하기도 합니다. |
| Esc | (편집 모드) 편집을 취소하고 셀 탐색 모드로 돌아갑니다. |
사용 예
table 요소로 만든 그리드
<td>는 자동으로 gridcell이 됩니다. 현재 셀만 tabindex="0"입니다.
<table role="grid" aria-label="이번 주 일정">
<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>
<tr><th scope="row">화</th><td tabindex="-1">교육</td><td tabindex="-1" aria-selected="true">휴가</td></tr>
</table>div로 만든 그리드
<div role="grid" aria-label="좌석 선택" aria-multiselectable="true">
<div role="row">
<div role="gridcell" tabindex="0" aria-selected="false">A1</div>
<div role="gridcell" tabindex="-1" aria-selected="true">A2</div>
<div role="gridcell" tabindex="-1" aria-disabled="true">A3 (판매 완료)</div>
</div>
</div>가상화된 그리드의 위치 정보
<div role="grid" aria-rowcount="1000" aria-colcount="8">
<div role="row" aria-rowindex="250">
<div role="gridcell" aria-colindex="1">250번 주문</div>
</div>
</div>row 없이 셀만 나열하는 실수
<div role="grid">
<div role="gridcell">A1</div> <!-- gridcell은 반드시 row 안에 있어야 합니다 -->
</div>화면낭독기에서는
| 상황 | 들리는 안내 (예) |
|---|---|
| 그리드 안 셀로 이동 | 오후, 열 3, 화, 휴가, 선택됨 |
| 편집 불가 셀에 포커스 | 회의, 읽기 전용 |
사용 지침
이렇게 쓰세요
- 반드시
row안에 넣고, 행은grid·treegrid(또는 그 안의rowgroup) 안에 넣습니다. - 열 제목·행 제목 셀을 함께 제공해 셀의 맥락이 읽히게 합니다.
- 그리드 안에서는 로빙 tabindex로 탭 순서를 하나로 유지합니다.
이렇게 쓰지 마세요
- 읽기 전용 데이터 표에 grid/gridcell을 쓰지 않습니다.
table/cell을 씁니다. - 모든 셀에
tabindex="0"을 주어 탭 키를 수십 번 누르게 만들지 않습니다.
관련 역할·패턴
이 역할을 쓰는 패턴