웹 접근성을 높이기 위해 WAI-ARIA(웹 접근성 이니셔티브 - 접근성 리치 인터넷 애플리케이션) 속성을 활용해 팝업을 만드는 방법과 tabindex 속성을 이용해 팝업 내부 영역에서만 포커스가 이동하도록 하는 방법에 대해 설명해드리겠습니다.
WAI-ARIA 속성은 웹 애플리케이션의 접근성을 높이기 위해 사용됩니다. 팝업을 만들 때 주로 사용되는 WAI-ARIA 속성은 다음과 같습니다:
role="dialog": 해당 요소가 대화 상자(popup)임을 스크린 리더에게 알려줍니다.
aria-labelledby: 팝업의 제목을 참조하는 속성으로, 팝업의 제목 요소의 id를 지정합니다.
aria-describedby: 팝업의 설명을 참조하는 속성으로, 팝업 내용 요소의 id를 지정합니다.
aria-hidden: 팝업이 보이지 않거나 접근할 수 없을 때 true로 설정하여 스크린 리더에게 이를 알립니다.
팝업 내부에서만 포커스가 이동하도록 하기 위해서는 tabindex 속성을 활용합니다. 이를 위해 포커스 트랩(focus trap)을 설정할 수 있습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Accessible Popup Example</title>
<style>
.popup {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid #ccc;
padding: 20px;
background-color: #fff;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.popup.active {
display: block;
}
</style>
</head>
<body>
<button id="openPopupBtn">Open Popup</button>
<div id="popup" class="popup" role="dialog" aria-labelledby="popupTitle" aria-describedby="popupDescription" aria-hidden="true">
<h2 id="popupTitle">Popup Title</h2>
<p id="popupDescription">This is a description of the popup content.</p>
<button id="closePopupBtn">Close Popup</button>
</div>
<script>
const openPopupBtn = document.getElementById('openPopupBtn');
const closePopupBtn = document.getElementById('closePopupBtn');
const popup = document.getElementById('popup');
openPopupBtn.addEventListener('click', () => {
popup.classList.add('active');
popup.setAttribute('aria-hidden', 'false');
closePopupBtn.focus();
});
closePopupBtn.addEventListener('click', () => {
popup.classList.remove('active');
popup.setAttribute('aria-hidden', 'true');
openPopupBtn.focus();
});
// Focus trap implementation
popup.addEventListener('keydown', (event) => {
if (event.key === 'Tab') {
const focusableElements = popup.querySelectorAll('button');
const firstElement = focusableElements[0];
const lastElement = focusableElements[focusableElements.length - 1];
if (event.shiftKey) {
if (document.activeElement === firstElement) {
lastElement.focus();
event.preventDefault();
}
} else {
if (document.activeElement === lastElement) {
firstElement.focus();
event.preventDefault();
}
}
}
if (event.key === 'Escape') {
closePopupBtn.click();
}
});
</script>
</body>
</html>
팝업을 열기 위한 버튼과 팝업 자체로 구성됩니다. 팝업은 role="dialog", aria-labelledby, aria-describedby 등의 WAI-ARIA 속성을 가집니다.
팝업의 기본 상태는 display: none으로 숨겨져 있습니다.
팝업 열기 버튼을 클릭하면 팝업이 나타나고, aria-hidden 속성이 false로 설정됩니다. 동시에 팝업 내부의 닫기 버튼으로 포커스를 이동합니다.
팝업 닫기 버튼을 클릭하면 팝업이 사라지고, aria-hidden 속성이 true로 설정되며, 다시 팝업 열기 버튼으로 포커스가 돌아갑니다.
팝업 내부에서 Tab 키를 눌렀을 때 포커스가 팝업 내부의 첫 번째와 마지막 포커스 가능한 요소 사이에서만 이동하도록 합니다.
Shift + Tab 조합으로 역방향으로 이동할 때와 일반 Tab 키로 순방향으로 이동할 때의 포커스 이동을 제어합니다.
Escape 키를 눌렀을 때 팝업이 닫히도록 합니다.
이렇게 하면 사용자가 키보드를 통해 팝업을 쉽게 열고 닫을 수 있으며, 팝업이 열린 동안 포커스가 팝업 내부에서만 이동하도록 보장하여 접근성을 높일 수 있습니다.