아티클

Modal.js를 활용한 모달 대화상자 접근성 개선하기

2022-03-11 11:23:46

안녕하세요, 엔비전스입니다.

웹페이지 내에서 기존 레이아웃에 중첩된 형태로 모달 대화상자를 구현할 때 접근성과 관련해서 고려해야 할 사항들이 많습니다. 그중 하나는 레이어에 가려져 클릭이 불가능한 요소들은 스크린 리더 및 키보드로도 접근이 되지 않도록 해야 한다는 것입니다.

화면상에서 다른 요소에 가려진 요소들은 브라우저 입장에서는 실질적으로 사라진 것이 아니기 때문에 접근성 노드에서 해당 요소들을 강제로 숨기고 Tab, Shift + Tab 키를 눌렀을 때 대화상자 바깥으로 나가지 못하도록 여러 스크립트를 구현해야 합니다.

이러한 작업들을 좀 더 간단하게 구현할 수 있도록 본 문서에서는 improveAccessibility 내에 modalDialog() 메서드를 만들어 사용방법을 공유하도록 하겠습니다.

 

modalDialog()의 특징

improveAccessibility.js 내의 modalDialog() 메서드는 다음과 같은 특징이 있습니다.

  1. improveAccessibility.js 파일 내에서 modalDialog() 메서드를 실행하는 것만으로 접근성과 관련된 별다른 스크립트 구현 없이 모달 대화상자와 관련된 마크업만 정확하게 해 주면 관련 접근성이 자동 구현됩니다.
  2. js에 구현된 접근성 기능으로는 다음과 같은 것들이 있습니다.
    1. 대화상자가 열렸을 때 대화상자의 특정 요소로 초점 보내기.
    2. 대화상자가 열렸을 때 Tab이나 Shift + Tab 키 눌러도 대화상자 외부로 초점 가지 않게 하기.
    3. 대화상자가 열렸을 때 aria-modal=”true” 미지원 스크린 리더를 위해 대화상자가 포함된 영역 이외의 모든 영역에 aria-hidden=”true” 적용.
    4. ESC 키로 대화상자 레이어 닫기 가능.
    5. 대화상자를 닫았을 때 초점을 원래의 대화상자를 여는 버튼으로 돌리고 기존 aria-hidden=”true” 속성 제거.

 

기본 마크업

  1. improveAccessibility.js 파일을 HTML 파일에서 다음 예시와 같이 불러옵니다.
    <script src="https://a11y-nvisions.github.io/js/improveAccessibility.js"></script>
  2. 대화상자를 여는 버튼에는 aria-haspopup=”dialog” 속성과 aria-controls 속성을 추가합니다. Aria-haspopup 속성은 스크린 리더가 대화상자를 여는 버튼에 포커스 했을 때 단순히 버튼이라고 읽지 않고 대화상자 팝업 등으로 읽게 함으로써 실행하면 팝업이 열릴 것임을 예상하도록 도와줍니다.
  3. aria-controls는 대화상자를 여는 버튼과 대화상자 영역을 서로 연결시켜 주는 역할을 하며 대화상자 영역에 id를 지정하여 연결합니다. 예를 들어 대화상자 영역의 id가 dialogPopup이라면 대화상자를 여는 버튼에는 다음과 같이 HTML을 작성할 수 있겠습니다.
    <button aria-haspopup=”dialog” aria-controls=”dialogPopup”>문의하기</button>
  4. 대화상자 영역에는 role=”dialog”, aria-modal=”true” 속성을 줍니다. Role=”dialog”는 말 그대로 해당 영역은 대화상자 영역이라는 것을 알리는 것이고 aria-modal=”true”는 해당 대화상자 영역만 접근성 노드에 표시하겠다는 것입니다.
    단 위의 두 속성은 반드시 대화상자가 표시되었을 때는 display:block, 사라졌을 때는 display:none으로 변경되는 영역에 주어야 합니다. 본 js는 대화상자와 관련된 속성들이 들어 있는 요소의 display 스타일 변경에 따라 초점을 돌려주거나 모달과 관련이 없는 부분들을 숨기는 등의 작업을 수행하기 때문입니다. 혹은 대화상자가 열리거나 닫혔을 때 aria-hidden 속성이 변경되는 곳이어도 됩니다.
    대화상자가 열렸다는 가정 하에 대화상자 영역 div에는 다음 예시와 같이 HTML을 작성할 수 있겠습니다.
    <div style=”display: block;” role=”dialog” aria-modal=”true” id=”dialogPopup”>
  5. 대화상자가 열렸을 때 초점을 특정 요소로 보내주어야 한다면, 초점을 보내 주어야 하는 요소에 autoFocus 클래스를 추가합니다. 다만 기존 페이지에서 이미 접근성 초점을 대화상자 내부로 보내주고 있다면 해당 클래스는 필요하지 않습니다.
  6. 대화상자가 표시되었을 때 대화상자 내부 요소 중 첫 번째 포커스 되는 요소와 마지막에 포커스 되는 요소에 각각 firstTab, lastTab 클래스를 추가합니다. 그러면 마지막 요소와 첫번째 요소에서 각각 tab과 Shift + Tab 키를 눌렀을 때, 이 두 클래스를 기준으로 초점이 대화상자 내부 콘텐츠 사이에서만 순환하게 됩니다. 만약 대화상자 내부에 확인 버튼과 같이 초점을 줄 수 있는 요소가 하나뿐인 경우에는 firstTab 클래스만 추가하면 됩니다. firstTab, lastTab CSS 속성이 없으면 대화상자 내부에서 초점이 가는 모든 요소들을 가져와서 자동으로 첫 번째 탭과 마지막 탭을 지정하게 되어 firstTab, lastTab 은 필수는 아닙니다.
  7. 대화상자를 닫는 버튼에는 closeModal 클래스를 추가합니다. 그러면 대화상자가 열렸을 때 ESC 키를 누르면 대화상자가 닫힙니다.
  8. 대화상자 팝업이 위의 조건과 같이 마크업되어 있다면 modalDialog() 메서드를 실행합니다.

 

모달 대화상자를 구현 시 참고사항

다음은 필수는 아니지만 스크린 리더 사용자의 사용성을 조금 더 향상시킬 수 있는 참고 사항들을 기술합니다.

  1. 대화상자가 열렸을 때 초점을 주는 곳은 <div> 와 같은 대화상자 영역 자체보다는 버튼, 링크, 편집창과 같은 초점 가능한 요소에 주는 것이 좋습니다. 이는 영역에 주게 되면 대화상자가 열렸을 때 스크린 리더가 대화상자 영역의 전체 내용을 연속적으로 읽게 되므로 음성으로 출력되는 메시지가 간결하지 못하기 때문입니다.
  2. Role=”dialog” 요소에는 aria-label 혹은 aria-labelledby 속성을 지정하여 대화상자 제목을 포함시키는 것이 좋습니다. 이렇게 하면 어떤 대화상자인지를 읽어주게 됩니다.
  3. 알림을 목적으로 하는 대화상자인 경우에는 role=”dialog” 대신 role=”alertdialog” 속성을 사용합니다.
  4. 대화상자가 열렸을 때 초점을 보내지 않고 특정 내용을 처음에 읽을 수 있게 하려면 aria-describedby 속성을 사용할 수 있습니다.

 

지금까지 modal.js를 활용한 대화상자 접근성 개선하기에 대해 함께 살펴보았습니다. 해당 js 파일을 열면 사용방법에 대한 주석이 포함되어 있으므로 참고하시기 바랍니다.

improveAccessibility.js 다운로드

댓글 0
댓글을 작성하려면 해주세요.