역할 · 복합 위젯
role="tablist"
탭(tab)들을 담는 목록입니다. 탭 목록은 탭 순서에서 한 번만 멈추고, 안에서는 방향키로 이동합니다.
한눈에 보기
- 분류
- 복합 위젯
- 대응 HTML
- 없음
- 이름 정하는 방법
- 작성자
- 이름 필수
- 아니요
- 필수 상위 요소
- 없음
- 필수 하위 요소
tab
설명
tablist는 tab을 담는 컨테이너이며, 필수 하위 요소는 tab입니다. 각 탭은 tabpanel을 하나씩 제어합니다. 이름은 필수가 아니지만 aria-label이나 aria-labelledby로 “상품 정보”처럼 탭 묶음의 주제를 알려 주면 좋습니다.
aria-orientation— 기본값은 가로(horizontal). 탭을 세로로 쌓았다면vertical로 바꾸고 ↑/↓로 이동하게 합니다.aria-multiselectable— 여러 패널을 동시에 펼칠 수 있는 구조에 쓰도록 정의되어 있지만, 실제로는 이런 경우 아코디언 패턴을 쓰는 것이 일반적입니다.
탭 목록 안에는 탭만 둡니다. 레이아웃 때문에 탭을 <li>로 감쌌다면 <li>에 role="none"(또는 presentation)을 붙여 소유 관계가 끊기지 않게 합니다. 탭 목록 안에 “탭 추가” 같은 버튼이 필요하면 탭 목록 밖에 둡니다.
자동 활성화 vs 수동 활성화
APG는 패널 내용을 지연 없이 보여 줄 수 있으면 포커스만 옮겨도 패널이 바뀌는 자동 활성화를 권장하고, 패널 전환에 네트워크 요청 등 지연이 있으면 Enter/Space를 눌러야 바뀌는 수동 활성화를 권장합니다. 아래 데모는 세로 + 수동 활성화입니다. 가로 + 자동 활성화 데모는 tab 페이지에 있습니다.
테스터 관점
- 세로 탭인데
aria-orientation="vertical"이 빠져 있거나, 방향키 방향이 화면 배치와 맞지 않는지 확인합니다. - 탭 목록 안에 탭이 아닌 요소가 섞여 있지 않은지 확인합니다.
함께 쓰는 속성
지원 속성
전역 속성(이름·설명 등)은 모든 역할에 쓸 수 있어 생략했습니다.
키보드 동작
| 키 | 동작 |
|---|---|
| Tab | 탭 목록으로 들어오면 선택된 탭에 포커스가 갑니다. 탭 목록 안에서 누르면 활성 탭 패널로 이동합니다. |
| → / ↓ | 가로 탭 목록은 →, 세로 탭 목록은 ↓로 다음 탭에 이동합니다(끝에서 처음으로 순환). |
| ← / ↑ | 가로 탭 목록은 ←, 세로 탭 목록은 ↑로 이전 탭에 이동합니다. |
| Home | (선택 사항) 첫 탭으로 이동합니다. |
| End | (선택 사항) 마지막 탭으로 이동합니다. |
| Enter | (수동 활성화) 포커스된 탭을 선택하고 패널을 표시합니다. |
| Space | (수동 활성화) Enter와 같습니다. |
| Delete | (선택 사항) 삭제할 수 있는 탭을 지웁니다. |
사용 예
세로 탭 목록
<div role="tablist" aria-label="계정 설정" aria-orientation="vertical">
<button type="button" role="tab" id="t-profile" aria-selected="true" aria-controls="p-profile">프로필</button>
<button type="button" role="tab" id="t-alert" aria-selected="false" aria-controls="p-alert" tabindex="-1">알림</button>
</div>li 래퍼가 있을 때
<ul role="tablist" aria-label="게시판">
<li role="none"><a role="tab" href="#p1" id="t1" aria-selected="true" aria-controls="p1">공지</a></li>
<li role="none"><a role="tab" href="#p2" id="t2" aria-selected="false" aria-controls="p2" tabindex="-1">자유</a></li>
</ul>방향 전환
var vertical = list.getAttribute('aria-orientation') === 'vertical';
var NEXT = vertical ? 'ArrowDown' : 'ArrowRight';
var PREV = vertical ? 'ArrowUp' : 'ArrowLeft';탭 목록에 버튼을 섞는 실수
<div role="tablist">
<button role="tab">탭 1</button>
<button>+ 새 탭</button> <!-- 탭이 아닌 자식 -->
</div>직접 해 보기
세로 탭 목록입니다(aria-orientation="vertical"). ↑ ↓로 포커스를 옮긴 뒤 Enter나 Space를 눌러야 패널이 바뀌는 수동 활성화 방식입니다.
이름과 프로필 사진을 바꿉니다.
이메일·앱 알림을 설정합니다.
비밀번호와 2단계 인증을 관리합니다.
실시간 코드 — 조작하면 속성 값이 바뀌는 모습을 볼 수 있습니다
화면낭독기에서는
| 상황 | 들리는 안내 (예) |
|---|---|
| 탭 목록으로 이동 | 계정 설정, 탭 목록, 세로, 프로필, 탭, 선택됨, 1/3 |
| ↓로 포커스 이동(수동 활성화) | 알림, 탭, 선택 안 됨, 2/3 |
| Enter로 선택 | 선택됨 |
사용 지침
이렇게 쓰세요
- 탭만 직접 자식으로 두고, 래퍼에는
role="none"을 줍니다. - 세로 배치면
aria-orientation="vertical"과 ↑/↓를 씁니다. - 패널 전환이 느리면 수동 활성화를 고릅니다.
이렇게 쓰지 마세요
- 탭 목록 안에 탭이 아닌 상호작용 요소를 넣지 않습니다.
- 페이지 이동용 메뉴를 탭 목록으로 만들지 않습니다.
관련 역할·패턴
이 역할을 쓰는 패턴