ARIA 접근성 가이드

속성 · 위젯 상태

aria-haspopup

요소를 조작하면 메뉴·목록·트리·그리드·대화상자 같은 팝업이 열린다는 것과 그 종류를 알립니다.

중급

한눈에 보기

구분
속성 (Property)
분류
위젯 상태
값 형식
토큰 (false / true / menu / listbox / tree / grid / dialog)
기본값
false
적용 범위
특정 역할에만 사용
HTML 대체
없음 (<select>는 목록 팝업 정보가 자동으로 전달됩니다)

설명

aria-haspopup은 요소를 누르거나 조작했을 때 상호작용할 수 있는 팝업이 나타난다는 것, 그리고 그 팝업의 역할이 무엇인지를 알립니다. 화면낭독기는 “하위 메뉴”, “대화 상자 열기” 등으로 읽어, 사용자가 이 버튼이 바로 동작을 실행하는 버튼이 아니라 선택지를 띄우는 버튼임을 알 수 있게 합니다.

값은 팝업의 역할과 정확히 같아야 합니다. role="menu"를 띄우면 menu(또는 같은 뜻인 true), role="listbox"면 listbox, role="dialog"면 dialog입니다. 흔한 실수는 단순한 링크 목록이나 펼침 영역을 띄우면서 aria-haspopup="true"를 쓰는 것입니다. true는 menu와 같은 뜻이라 사용자는 방향키로 이동하는 메뉴를 기대하게 됩니다. 메뉴 역할이 아닌 일반 펼침 영역이면 aria-expanded만 씁니다.

팝업이 열렸는지는 이 속성이 아니라 aria-expanded로 알립니다. 메뉴 버튼은 보통 aria-haspopup="menu"와 aria-expanded="false"로 시작해, 메뉴가 열리면 aria-expanded="true"로 바꿉니다. combobox는 기본값이 listbox여서, 목록 상자를 띄운다면 따로 쓰지 않아도 됩니다. 툴팁은 상호작용하는 팝업이 아니므로 이 속성을 쓰지 않습니다.

전역 사용은 ARIA 1.2에서 사용 중단

WAI-ARIA 1.1까지 aria-haspopup은 모든 요소에 쓸 수 있는 전역 속성이었지만, WAI-ARIA 1.2에서 전역 사용이 사용 중단(deprecated)되어 아래 “사용할 수 있는 역할”에 나열된 역할(과 그 역할을 상속하는 역할)에만 쓰도록 바뀌었습니다.

테스트할 때는 버튼에서 팝업 종류가 읽히는지, 실제로 열리는 요소의 역할이 값과 같은지, 열린 팝업 안에서 해당 역할에 맞는 키보드 동작(메뉴라면 방향키·Esc)이 되는지, 닫힌 뒤 포커스가 버튼으로 돌아오는지 확인합니다. 브라우저·화면낭독기에 따라 dialog·grid 등 일부 값을 모두 menu처럼 읽기도 합니다.

값

값
값의미
false 기본값팝업이 없습니다.
true팝업이 있으며, 그 역할은 menu입니다. (menu와 같은 뜻)
menu메뉴(role="menu")가 열립니다.
listbox목록 상자(role="listbox")가 열립니다.
tree트리(role="tree")가 열립니다.
grid그리드(role="grid")가 열립니다. 예: 날짜 선택 달력.
dialog대화상자(role="dialog")가 열립니다.

사용 예

메뉴 버튼

권장HTML
<button type="button" id="export-btn" aria-haspopup="menu" aria-expanded="false" aria-controls="export-menu">내보내기</button>
<ul id="export-menu" role="menu" aria-labelledby="export-btn" hidden>
  <li role="menuitem" tabindex="-1">PDF로 저장</li>
  <li role="menuitem" tabindex="-1">엑셀로 저장</li>
</ul>

날짜 선택 대화상자를 여는 버튼

HTML
<button type="button" aria-haspopup="dialog" aria-label="날짜 선택">📅</button>

일반 펼침 메뉴에 true 사용 (비권장)

비권장HTML
<button type="button" aria-haspopup="true" aria-expanded="false" aria-controls="nav-list">카테고리</button>
<ul id="nav-list" hidden>
  <li><a href="/a">가전</a></li>
  <li><a href="/b">가구</a></li>
</ul>

링크 목록은 menu가 아닙니다. aria-haspopup을 빼고 aria-expanded만 쓰는 디스클로저로 만듭니다.

직접 해 보기

“내보내기” 버튼을 누르거나 포커스 후 아래 방향키를 눌러 메뉴를 여세요. 메뉴 안에서는 위·아래 방향키, Home·End로 이동하고 Enter로 실행, Esc로 닫습니다.

화면낭독기에서는

화면낭독기 안내 예시 (표현은 화면낭독기·브라우저·버전에 따라 조금씩 다릅니다)
상황들리는 안내 (예)
aria-haspopup="menu" 버튼에 포커스내보내기, 메뉴 버튼, 하위 메뉴, 축소됨
아래 방향키로 메뉴 열기내보내기, 메뉴, PDF로 저장, 메뉴 항목, 1/3
aria-haspopup="dialog" 버튼에 포커스날짜 선택, 버튼, 대화 상자 열기
aria-haspopup="listbox" 버튼에 포커스정렬 기준, 버튼, 목록 열기, 축소됨

사용 지침

이렇게 쓰세요

  • 값을 실제로 열리는 팝업의 역할과 같게 맞춥니다.
  • 팝업의 열림 상태는 aria-expanded로 함께 알립니다.
  • 팝업 역할에 맞는 키보드 동작과 닫힌 뒤 포커스 복귀를 구현합니다.

이렇게 쓰지 마세요

  • 링크 목록이나 단순 펼침 영역에 true/menu를 쓰지 않습니다.
  • 툴팁처럼 상호작용하지 않는 팝업에 쓰지 않습니다.
  • role="listbox"를 띄우는 콤보 상자에 중복으로 쓰지 않아도 됩니다(기본값이 listbox).
  • 1.2에서 지원하지 않는 역할(일반 텍스트 등)에 쓰지 않습니다.

사용할 수 있는 역할

이 속성을 쓰는 패턴

참고 자료