역할 · 위젯
role="menuitem"
메뉴(menu)나 메뉴 막대(menubar) 안에서 명령을 실행하거나 하위 메뉴를 여는 항목입니다.
한눈에 보기
- 분류
- 위젯
- 대응 HTML
- 없음 (HTML
<menu>는 목록이며 이 역할이 아닙니다) - 이름 정하는 방법
- 콘텐츠, 작성자
- 이름 필수
- 예
- 필수 하위 요소
- 없음
설명
menuitem은 menu 또는 menubar(또는 그 안의 group) 안에 들어가는 명령 항목입니다. 프로그램의 “파일 › 저장”처럼 고르면 동작을 실행하거나, aria-haspopup과 aria-expanded를 가진 경우 하위 메뉴를 엽니다. 켜고 끄는 항목은 menuitemcheckbox, 여러 개 중 하나를 고르는 항목은 menuitemradio를 씁니다.
메뉴 역할을 쓰면 화면낭독기는 애플리케이션 메뉴로 인식하고, 사용자는 방향키로 이동할 것을 기대합니다. 따라서 메뉴 항목은 직접 포커스를 받아야 하고(로빙 tabindex 또는 aria-activedescendant), APG 메뉴 키보드 규칙을 모두 구현해야 합니다.
사이트 내비게이션은 메뉴가 아닙니다
웹사이트 상단의 링크 목록을 menubar/menuitem으로 만들면 화면낭독기 사용자는 링크 목록 탐색, Tab 이동 같은 익숙한 방법을 쓸 수 없게 됩니다. 사이트 내비게이션은 <nav> 안의 링크 목록(필요하면 button + aria-expanded로 펼치는 디스클로저)으로 만듭니다. 메뉴 역할은 데스크톱 앱처럼 명령을 고르는 UI에만 씁니다.
메뉴 항목은 이름을 콘텐츠에서 가져옵니다. 단축키를 함께 표시한다면 aria-keyshortcuts로 알릴 수 있고, 보이는 단축키 글자는 aria-hidden="true"로 이름에서 빼는 것이 깔끔합니다. 메뉴 항목 사이에 DOM 구조 때문에 <li>가 끼면 role="none"으로 목록 의미를 없앱니다.
테스터 관점
- 메뉴가 열리면 포커스가 첫(또는 마지막) 항목으로 옮겨지는지, Esc로 닫으면 메뉴를 연 버튼으로 돌아오는지 확인합니다.
- 항목 수와 위치(“2/5”)가 읽히는지 확인합니다. DOM 구조가 복잡하면
aria-posinset/aria-setsize가 필요할 수 있습니다. - 비활성 항목은
aria-disabled="true"로 표시되고, 포커스는 받되 실행되지 않는지 확인합니다(APG는 비활성 메뉴 항목도 포커스 가능하게 두기를 권장합니다).
함께 쓰는 속성
지원 속성
전역 속성(이름·설명 등)은 모든 역할에 쓸 수 있어 생략했습니다.
키보드 동작
| 키 | 동작 |
|---|---|
| Enter | 하위 메뉴가 있으면 열고 첫 항목으로 포커스를 옮깁니다. 없으면 항목을 실행하고 메뉴를 닫습니다. |
| Space | (선택 사항) Enter와 같이 동작합니다. |
| ↓ | 세로 메뉴: 다음 항목으로 이동합니다(마지막에서 처음으로 순환은 선택 사항). 메뉴 막대 항목: 하위 메뉴를 열고 첫 항목으로 이동합니다. |
| ↑ | 세로 메뉴: 이전 항목으로 이동합니다. 메뉴 막대 항목: (선택 사항) 하위 메뉴를 열고 마지막 항목으로 이동합니다. |
| → | 하위 메뉴가 있는 세로 메뉴 항목: 하위 메뉴를 열고 첫 항목으로 이동합니다. 메뉴 막대 항목: 다음 메뉴 막대 항목으로 이동합니다. |
| ← | 하위 메뉴 안: 하위 메뉴를 닫고 부모 항목으로 돌아갑니다. 메뉴 막대 항목: 이전 메뉴 막대 항목으로 이동합니다. |
| Home | 첫 항목으로 이동합니다. |
| End | 마지막 항목으로 이동합니다. |
| Esc | 메뉴를 닫고 메뉴를 연 요소(메뉴 버튼 또는 부모 메뉴 항목)로 포커스를 돌려보냅니다. |
| Tab | 메뉴를 모두 닫고 페이지의 다음 포커스 요소로 이동합니다. 메뉴 안 항목 사이 이동에는 쓰지 않습니다. |
| 글자 키 | (선택 사항) 그 글자로 시작하는 다음 항목으로 이동합니다. |
사용 예
메뉴 버튼과 메뉴 항목
<button type="button" id="edit-btn" aria-haspopup="menu"
aria-expanded="false" aria-controls="edit-menu">편집</button>
<ul role="menu" id="edit-menu" aria-labelledby="edit-btn" hidden>
<li role="menuitem" tabindex="-1">잘라내기</li>
<li role="menuitem" tabindex="-1">복사</li>
<li role="menuitem" tabindex="-1" aria-disabled="true">붙여넣기</li>
</ul>하위 메뉴를 여는 항목
<li role="none">
<span role="menuitem" tabindex="-1" aria-haspopup="menu" aria-expanded="false">내보내기</span>
<ul role="menu" aria-label="내보내기" hidden>
<li role="menuitem" tabindex="-1">PDF</li>
<li role="menuitem" tabindex="-1">Word</li>
</ul>
</li>단축키 표시
<li role="menuitem" tabindex="-1" aria-keyshortcuts="Control+C">
복사 <span aria-hidden="true">Ctrl+C</span>
</li>사이트 내비게이션을 메뉴로 만드는 실수
<ul role="menubar">
<li role="menuitem"><a href="/about">회사 소개</a></li>
</ul>
<!-- 링크 목록이라면 <nav> 안의 <ul><li><a>로 충분합니다 -->직접 해 보기
“편집” 버튼으로 메뉴를 열고 ↑ ↓ Home End로 이동해 보세요. Enter로 실행하면 메뉴가 닫히고 버튼으로 포커스가 돌아갑니다. “붙여넣기”는 비활성 항목이라 포커스는 가지만 실행되지 않습니다.
실시간 코드 — 조작하면 속성 값이 바뀌는 모습을 볼 수 있습니다
화면낭독기에서는
| 상황 | 들리는 안내 (예) |
|---|---|
| 메뉴 버튼에서 메뉴를 엶 | 편집, 메뉴, 잘라내기, 메뉴 항목, 1/4 |
| 비활성 항목으로 이동 | 붙여넣기, 사용할 수 없음, 메뉴 항목, 3/4 |
| 하위 메뉴가 있는 항목 | 내보내기, 하위 메뉴, 메뉴 항목, 축소됨 |
사용 지침
이렇게 쓰세요
- 반드시
menu/menubar(또는 그 안의group) 안에 넣습니다. - 사이에 끼는
<li>·래퍼에는role="none"을 붙여 소유 관계를 깨지 않게 합니다. - 메뉴가 닫히면 포커스를 메뉴를 연 요소로 돌려보냅니다.
이렇게 쓰지 마세요
- 사이트 내비게이션 링크 목록에 메뉴 역할을 쓰지 않습니다.
- 메뉴 항목 사이를 Tab으로 이동하게 만들지 않습니다. 방향키로 이동합니다.
- 메뉴 항목 안에 버튼·링크 같은 다른 상호작용 요소를 넣지 않습니다.
관련 역할·패턴
이 역할을 쓰는 패턴