속성 · 위젯 상태
aria-modal
대화상자가 모달이라서, 열려 있는 동안 바깥 콘텐츠를 사용할 수 없다는 것을 알립니다.
한눈에 보기
- 구분
- 속성 (Property)
- 분류
- 위젯 상태
- 값 형식
- true / false
- 기본값
false- 적용 범위
- 특정 역할에만 사용
- HTML 대체
<dialog>의showModal()(바깥 콘텐츠를 자동으로 비활성화)
설명
aria-modal="true"는 dialog나 alertdialog가 모달이라는 것, 즉 열려 있는 동안 대화상자 바깥의 콘텐츠는 사용할 수 없다는 것을 보조기술에 알립니다. 이를 지원하는 화면낭독기는 가상 커서가 대화상자 밖으로 나가지 않도록 바깥 콘텐츠를 탐색 대상에서 제외합니다.
이 속성은 실제로 바깥을 막아 주지 않습니다. 모달이라고 알렸다면 작성자가 다음을 모두 구현해야 합니다. 열릴 때 대화상자 안으로 포커스 이동, Tab·Shift+Tab이 대화상자 안에서만 순환(포커스 가두기), Esc로 닫기, 닫은 뒤 대화상자를 연 요소로 포커스 복귀, 바깥 콘텐츠의 시각적 가림(배경 막). 이 중 하나라도 빠지면 키보드 사용자가 대화상자 뒤의 요소로 빠져나가거나, 화면낭독기 사용자가 대화상자를 찾지 못하게 됩니다.
가능하면 HTML <dialog> 요소를 showModal()로 여는 방법을 우선 검토합니다. 바깥 콘텐츠가 자동으로 비활성(inert)되고 Esc 닫기도 기본 제공되며, 브라우저가 모달 상태를 접근성 API에 전달하므로 aria-modal을 따로 쓸 필요가 없습니다. 사용자 정의 대화상자를 쓴다면 aria-modal="true"와 함께 바깥 콘텐츠에 inert를 설정하는 방식이 가장 확실합니다.
바깥 콘텐츠를 계속 사용할 수 있는 비모달 대화상자(채팅 창, 찾기 패널 등)에는 true를 쓰면 안 됩니다. 사용할 수 있는 콘텐츠가 화면낭독기에서 사라지기 때문입니다. 또한 대화상자에는 aria-labelledby(제목)로 이름을 주고, 필요하면 aria-describedby로 안내 문구를 연결합니다.
테스트할 때는 대화상자가 열린 상태에서 Tab을 계속 눌러도 바깥으로 포커스가 나가지 않는지, 화면낭독기의 가상 커서(방향키)로 바깥 내용이 읽히지 않는지, Esc로 닫히고 원래 버튼으로 포커스가 돌아오는지 확인합니다.
값
| 값 | 의미 |
|---|---|
true | 모달입니다. 대화상자가 열려 있는 동안 바깥 콘텐츠는 사용할 수 없습니다. |
false 기본값 | 모달이 아닙니다. 바깥 콘텐츠도 계속 사용할 수 있습니다. |
사용 예
네이티브 모달 대화상자 (권장)
<button type="button" id="open">배송지 변경</button>
<dialog id="dlg" aria-labelledby="dlg-title">
<h2 id="dlg-title">배송지 변경</h2>
…
<button type="button" id="close">닫기</button>
</dialog>
<script>
open.addEventListener('click', function () { dlg.showModal(); });
close.addEventListener('click', function () { dlg.close(); });
</script>showModal()은 바깥을 자동으로 비활성화하고 Esc 닫기를 제공합니다. 닫은 뒤 포커스도 연 버튼으로 돌아갑니다.
사용자 정의 모달 대화상자
<div role="dialog" aria-modal="true" aria-labelledby="dlg-title" aria-describedby="dlg-desc">
<h2 id="dlg-title">변경 사항을 저장할까요?</h2>
<p id="dlg-desc">저장하지 않으면 입력한 내용이 사라집니다.</p>
<button type="button">저장</button>
<button type="button">취소</button>
</div>열고 닫을 때 처리
var opener;
function openDialog(dlg) {
opener = document.activeElement;
document.getElementById('page').inert = true; // 바깥 비활성
dlg.hidden = false;
dlg.querySelector('input, button').focus(); // 안으로 포커스 이동
}
function closeDialog(dlg) {
dlg.hidden = true;
document.getElementById('page').inert = false;
opener.focus(); // 포커스 복귀
}포커스 관리 없이 속성만 사용 (비권장)
<div class="layer-popup" role="dialog" aria-modal="true">
<p>이벤트 안내</p>
<a href="#" class="close">닫기</a>
</div>이름이 없고, 열릴 때 포커스가 이동하지 않으며 Tab으로 뒤쪽 콘텐츠에 갈 수 있다면 모달이라는 정보와 실제 동작이 어긋납니다.
직접 해 보기
“배송지 변경”을 누르면 모달 대화상자가 열립니다. Tab이 대화상자 안에서만 순환하는지, Esc로 닫히고 버튼으로 포커스가 돌아오는지 확인해 보세요.
배송지 변경
새 배송지를 입력하세요. Esc를 누르면 닫힙니다.
실시간 코드 — 조작하면 속성 값이 바뀌는 모습을 볼 수 있습니다
화면낭독기에서는
| 상황 | 들리는 안내 (예) |
|---|---|
| 모달 대화상자가 열리고 주소 입력란으로 포커스 이동 | 배송지 변경, 대화 상자, 새 배송지를 입력하세요. Esc를 누르면 닫힙니다. 주소, 편집 창 |
| 대화상자 안에서 가상 커서로 끝까지 이동 | (대화상자 밖의 내용은 읽히지 않음) |
| Esc로 닫은 뒤 | 배송지 변경, 버튼, 대화 상자 열기 |
사용 지침
이렇게 쓰세요
- 가능하면
<dialog>와showModal()을 씁니다. - 사용자 정의 모달은 포커스 이동·가두기·Esc 닫기·포커스 복귀를 모두 구현합니다.
aria-labelledby로 대화상자에 이름을 줍니다.- 바깥 콘텐츠에는
inert를 설정해 실제로 사용할 수 없게 만듭니다.
이렇게 쓰지 마세요
- 바깥을 계속 쓸 수 있는 비모달 대화상자에
true를 쓰지 않습니다. dialog·alertdialog가 아닌 요소에 쓰지 않습니다.- 속성만 붙이고 포커스 관리를 생략하지 않습니다.
- 바깥 콘텐츠를 숨기려고
aria-modal과aria-hidden을 중복으로 복잡하게 관리하지 않습니다.inert가 더 단순합니다.
사용할 수 있는 역할
관련 속성·패턴
이 속성을 쓰는 패턴