접근성을 고려한 팝업

Yujin·2023년 5월 17일
1

WAI-ARIA를 이용해 접근성을 개선하고, tabindex를 이용해 팝업 내부 영역에서만 이동하도록 하는 방법을 사용한 팝업 만들기

팝업 요소 설정하기

<button id="popupButton" aria-haspopup="true" aria-expanded="false">팝업 열기</button>
<div id="popup" role="dialog" aria-labelledby="popupHeading" aria-modal="true" tabindex="-1">
  <h2 id="popupHeading">팝업 제목</h2>
  <p>팝업 내용</p>
  <input type="text" placeholder="입력1" />
  <input type="text" placeholder="입력2" />
  <input type="text" placeholder="입력3" />
  <button id="closeButton">닫기</button>
</div>

aria-haspopup

aria-haspopup는 WAI-ARIA(웹 접근성 개선을 위한 인터랙티브 웹 애플리케이션) 스펙의 일부로, 요소가 팝업이나 메뉴와 같은 하위 항목을 가지고 있음을 나타내는 속성이다. 이 속성은 스크린 리더 등 보조 기술을 사용하는 사용자에게 해당 요소에 대한 상태를 알려줌으로써 접근성을 개선한다.

aria-haspopup 속성

  • true는 해당 요소가 하위 팝업이나 메뉴를 가지고 있다는 것을 나타낸다.
  • false는 해당 요소가 하위 팝업이나 메뉴를 가지고 있지 않음을 나타낸다.

aria-expanded

aria-expanded는 특정 요소가 접혀 있는지(축소 상태) 또는 펼쳐져 있는지(확장 상태)를 나타내는 속성이다.

aria-expanded 속성

  • true는 해당 요소가 펼쳐져 있음을 나타낸다.
  • false는 해당 요소가 접혀 있음을 나타낸다.

팝업창이 펼쳐지면 aria-expanded 속성의 값을 true로 변경하면 된다.

aria-modal

aria-modal은 특정 요소가 모달 대화 상자(모달 창)임을 나타내는 속성이다. 모달 창은 사용자의 주의를 요구하고, 배경 컨텐츠와의 상호작용을 제한하여 모달이 닫힐 때까지 사용자의 주의를 돌리지 않도록 한다.

aria-modal 속성

  • true는 해당 요소가 모달 창임을 나타낸다.
  • false는 해당 요소가 모달 창이 아님을 나타낸다.

위 예시에서 aria-modal='true' 속성은 role='dialog'가 설정된 요소가 모달 창 임을 나타낸다.

팝업 관련 동작 추가하기

팝업 내부의 요소들에게 tabindex를 할당하여 이동 가능하도록 설정한다.

const popupButton = document.getElementById('popupButton');
const popup = document.getElementById('popup');
const closeButton = document.getElementById('closeButton');

const popupContents = popup.querySelectorAll('a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])');

const enableTabindex = () => {
  popupContents.forEach((content) => {
    content.setAttribute('tabindex', '0');
  })
}

const disableTabindex = () => {
  popupContents.forEach((content) => {
    content.removeAttribute('tabindex');
  })
}

popupButton.addEventListener('click', () => {
  popup.style.display = 'block';
  popupButton.setAttribute('aria-expanded', 'true');
  enableTabindex();
  closeButton.focus();
});

closeButton.addEventListener('click', () => {
  popup.style.display = 'none';
  popupButton.setAttribute('aria-expanded', 'false');
  disableTabindex();
});

//tabindex 설정
popup.addEventListener('keydown', (e) => {
  const lastElement = popupContents[popupContents.length - 1];
  if (e.key === 'Tab') {
    if (e.target === lastElement) {
      e.preventDefault();
      popupContents[0].focus();
    }
  }
});

위 예시에서 팝업 버튼을 클릭하면 aria-expanded 속성을 변경하여 팝업이 열렸음을 알리고, 팝업 닫기 버튼을 클릭하면 팝업이 닫힌다.

팝업이 열렸을 경우, enableTabinx() 함수를 호출하여 팝업 내부의 포커스 가능한 요소들에게 tabindex를 설정한다. 팝업이 닫힐 때는 disableTabindex() 함수를 호출하여 tabindex 값을 초기 상태로 복원한다.

JavaScript를 사용하여 동적으로 tabindex를 적용하면 팝업이 열릴 때만 포커스 가능한 요소에 접근할 수 있게 되며, 팝업이 닫힐 때 tabindex는 제거되어 탭 키 이동의 순서에 영향을 주지 않는다.

Focus

웹은 사용자와 상호작용(interactive)이 가능한 요소는 기본적으로 키보드로 포커스가 잡히게 되어 있다. 대표적으로 <input>, <select>, <button>, <a>, <textarea>가 있다.

tabindex

👉🏻 tabindex는 HTML 요소의 키보드 포커스를 지정하는 데 사용되는 속성이다. 이 속성을 사용하면 사용자가 탭 키를 사용하여 요소 간에 이동할 수 있다.

tabindex 속성

  • 양의 정수(0보다 큰 값): 양의 정수를 지정하면 해당 요소가 탭 키 순서에 따라 포커스를 받을 수 있다. 작은 값부터 큰 값의 순서로 요소에 포커스가 이동한다. (접근성을 고려하면 권장되는 방법이 아니다.)
  • 0: 0을 지정하면 요소는 탭 키를 사용하여 포커스를 받을 수 있지만, 탭 키 순서는 요소의 위치에 따라 결정된다. 일반적으로 이 값을 사용하여 정적인 요소를 탭 순서에 추가한다.
  • 음의 정수(-1): 음의 정수를 지정하면 사용자는 탭 키를 눌러도 접근할 수 없으나, JavaScript에서 focus() 메서드를 호출해 포커스를 부여할 수 있다.

결과

profile
_〆(・_・。)

0개의 댓글