WWDC2022, iOS와 iPadOS의 WAI-ARIA 커스텀 컨트롤을 위한 접근성 API 지원 소식
안녕하세요, 엔비전스입니다. 지난여름 6월에 애플 세계 개발자 회의 2022(Worldwide Developer Conference 2022, 이하 WWDC)를 진행했습니다. 이번 WWDC에서는 iOS 16, iPadOS 16, macOS 13 Ventura, watchOS 9 소식과 함께 정말 유용하고 새로운 정보를 발표했습니다. WWDC에는 키노트 외에도 여러 세션 발표가 있습니다. 이번에 여러 세션 중, Accessibility & Inclusion 세션에서는 접근성에 관심이 있는 웹 개발자나 기업이 눈여겨봐야 할 반가운 개선사항을 발표했습니다. 바로, 전처리를 통한 WAI-ARIA 일부 위젯의 VoiceOver 제스처 동작 지원입니다.
WAI-ARIA 위젯을 구현할 때, 가장 고민되는 부분이 모바일 플랫폼 접근성입니다. 기본적으로 WAI-ARIA로 커스텀 요소를 만들 때, Javascript에서는 주로 키보드 조작, 마우스 조작 등의 이벤트를 구현하여, 마치, 웹페이지 안에 있는 요소가 네이티브 요소처럼 느껴지도록 동작하게끔 합니다. 데스크탑 접근성만 놓고 보자면, 마우스와 키보드 접근성, 요소 유형과 상태 정보를 제공하면, 매우 훌륭한 위젯입니다. 그런데, 오늘날 WAI-ARIA 위젯의 문제점은, Javascript의 이벤트만으로는 OS의 특성을 모두 반영할 수 없다는 것입니다.
OS 특성? 어떤 것이 있지요? 예를 들어주세요
오늘날 대부분의 상용 OS는 환경에 맞는 스크린리더를 따로 제공하고 있습니다. Windows나 Android의 경우, 접근성 API를 활용하여 특정 단체나 기업에서 스크린리더를 만들긴 했지만, 기본적으로 Narrator와 Talkback이 탑재돼 있고, macOS나 iOS는 VoiceOver가 탑재돼 있는걸로 이미 매우 유명합니다. 리눅스에서는 Orca라는 스크린리더를 설치할 수 있고, ChromeBook에서는 ChromeVox라는 스크린리더를 지원합니다.
이렇듯 많은 스크린리더, 많은 OS는 OS 특성에 맞게 보조 기술을 만들었습니다. 특히 모바일과 데스크탑은 조작이 많이 다르기 때문에, 플랫폼에서 제공하는 보조 기술도 모두 제각각입니다. 네이티브에서는 이것이 문제가 되지 않지만, 웹사이트는 하나의 HTML5라는 표준 언어로 구성한 표준 문서이기 때문에 반드시 문제가 생깁니다.
슬라이더 위젯을 예로 들어 보겠습니다. HTML에서는 OS마다 호환되는 기본 네이티브 슬라이더를 <input type=”range” max=”number” min=”number” value=”number” step=”number”>로 만들 수 있습니다. 개발자나 기업에서 이 range 유형의 input에 만족하면 다행이지만, 대부분 디자인이나 여러 이유로 커스텀 요소를 만듭니다. 모든 장치에 호환되는 슬라이더를 만들기 위해서는 어떤 이벤트가 PC 필요할까요? 한번 나열해 보겠습니다. 일반적인 막대형 슬라이더를 기준으로 하겠습니다.
- 포인터 이벤트: 당연하게도, click 이벤트가 필요합니다. 마우스 왼쪽 버튼으로 슬라이더의 원하는 부분을 클릭하면 해당 영역 비율만큼 수치가 올라가야 하니까요. 또, 마우스를 누른 상태로 끌어서 원하는 만큼 수치를 선택할 수도 있을 것입니다. mousedown, museleave, mouseup 등의 이벤트도 필요합니다. 또, touchEvent 계열이 필요할 수도 있습니다. 터치 디바이스가 오늘날 보편화되었으니까요. Touchmove, touchend, touchstart가 필요할 수 있겠습니다.
- 키보드 이벤트: 슬라이더는 일반적으로 방향과 관계없이 상/하 좌/우 화살표 키를 통해 슬라이더 값을 조절할 수 있게 합니다. Keydown 이벤트가 필요하겠지요. 왼쪽 화살표 키와 아래 화살표 키를 누르면 값이 감소하고, 오른쪽 화살표 키와 위 화살표 키를 누르면, 값이 증가합니다. 또한, 값이 너무 클 수도 있으니 Home과 End로 최댓값과 최솟값으로 바로 조절할 수 있게도 합니다.
자바스크립트에서 구현할 수 있는 기능은 위 두 가지로 볼 수 있습니다. VoiceOver나 Talkback을 잘 모르는 분이시라면, 위 두 개만 구현해도 훌륭한데 무슨 문제가 있겠느냐는 생각이 들겠는데요. 터치 디바이스에 탑재된 VoiceOver에서는 조절 가능(슬라이더를 iOS에서는 조절 가능, Adjustable이라 부름)에 초점을 두고, 손가락을 아래로 쓸면 값이 내려가고, 위로 쓸면 올라가는 값 조절을 위한 보조 기능을 제공합니다.
HTML은 표준 문서 마크업 언어이기 때문에, HTML에서 제공하는 태그는 모든 플랫폼에서 구현되어야 합니다. 그렇기 때문에, <input type=”range”> 태그를 사용하면, 접근성 문제가 전혀 발생하지 않는 것이지요. 그런데, 커스텀으로 구현된 슬라이더는 어떨까요? 네, 당연하게도 위에서 언급한 두 가지 외에 슬라이더를 조절할 방법은 없습니다.
이게 문제가 되는지 물어보실 수도 있습니다. 결론만 말하자면 아주 큰 문제가 됩니다.
개발자나 퍼블리셔는 코드를 보기 때문에, 커스텀 요소와 네이티브 태그 요소를 명확히 구분할 수 있습니다. 그런데, 스크린리더나 사용자는 이 둘을 구분할 수 없습니다. VoiceOver에서는 div에 role=”slider”를 주었건, input 유형을 range로 주었건, 무조건 “조절 가능, 값을 조절하려면 쓸어 올리거나 쓸어내리십시오”라는 안내를 하게 됩니다. 힌트를 켜 놓은 사용자는 당연히 안내에 따라 “위 또는 아래로” 한 손가락을 아래로 쓸어내리는 제스처를 통해 조절 동작을 시도할 겁니다. 될 리가 없겠지요? 우리는 구현한 적이 없으니까요. 그런데, 기존까지 안타깝게도, 이를 구현할 방법이 없었습니다. Javascript에서 OS의 API에 깊게 접근할 방법이 없기 때문입니다. 그리고, 다중 플랫폼을 포괄하는 웹 플랫폼 특성상, OS 별로 API에 접근하여 따로 개발 및 구현하게 하는 것은 취지에 맞지 않습니다.
그래서 어떻게 하면 되는데요?
기존에는 range 유형의 입력 요소의 스타일을 없애고 디자인하는 방법을 쓰거나, 모바일용 위젯을 따로 만드는 방식으로 해결해 왔습니다. 그런데, 이번 WWDC에서 이 문제를 아주 심플하게 해결했습니다.
iOS VoiceOver 제스처 API와 키보드 이벤트 간의 전처리
키보드의 키값을 제스처로 Accessibility & Inclusion 섹션의 “What’s new in web accessibility” 파트에서 특정 요소의 추가 제스처를 특정 키보드 이벤트의 키값과 매핑했음을 발표했습니다. 사용자가 조절 가능에서 위/또는 아래로 쓸면, 실제로는 키보드 이벤트가 발생하도록 말입니다. 이는 정말로 놀라운 발표였습니다. 물론 개발자의 노력이 필요한 부분이지만, 이는 매우 반가운 일이며, 이에 따라 웹 접근성은 한걸음 네이티브에 가까워졌습니다.
혹자는 이렇게 얘기할 수 있습니다. “Apple이 설계한 방식대로만 키보드 이벤트를 짜야 하는 것 아니냐?”라고 말이지요. 맞습니다. 하지만 옳은 일입니다. 네이티브에 있는 특정 요소를 그대로 구현하는 것이 목적이라면, 철저하게 이를 따라야 하고, W3C의 Wai-ARIA Practice와 같은 자료를 보더라도, 키보드 이벤트에 대해 명확히 정리돼 있습니다. 애플은 이러한 자료를 근거로 제스처와 매핑한 것입니다.
오늘부터 지원되는 커스텀 요소의 제스처
What’s new in web accessibility에서는 크게, 웹에서의 슬라이더 접근성, WebSpeech API, 대화상자 접근성에 대해 소개했습니다. 그중 우리가 눈 여겨봐야 할 것은 슬라이더와 모달 대화상자입니다. 이제, event.code, event.key 등의 방향키값이 VoiceOver 제스처에 매핑되어 알맞은 키 이벤트를 제공하면, 커스텀 슬라이더를 네이티브 슬라이더처럼 사용할 수 있습니다.
class AdjustableElement extends HTMLElement {
...
increasement(){...}
decreasement(){...}
switch(evt.code){
case "ArrowUp":
case "ArrowRight":
this.increasement();
break;
case "ArrowDown":
case "ArrowLeft":
this.decreasement();
break;
}
}
또한 모달 대화상자도 이와 비슷한 전처리 기술을 적용받습니다. 바로 ESC 키에 네이티브 API인 accessibilityPerformEscape()가 매핑된 것입니다. 이제, 웹 대화상자에서 닫기 버튼이 없어도, 닫기 메소드만 ESC 키를 눌러 작동하게 구현한다면, iOS 사용자는 대화상자 어디서든 대화상자를 닫을 수 있게 되었습니다.
아울러, 이 전처리 기술의 도입과 동시에 2022년 화제의 새로운 HTML5 요소인 <dialog>
요소도 지원을 시작했습니다.
그리고, 확인해 본 결과, 발표에서는 모달만을 예시로 언급하였으나, 콤보 상자, 메뉴 등 ESC 키로 닫는 커스텀 UI에는 대화상자와 동등하게 ESC 키에 accessibilityPerformEscape()가 적용되는 것을 확인했습니다.
이제, 개발자는 따로 고민할 것 없이, 단순하게 키보드 이벤트만을 올바르게 구현하면, VoiceOver 사용자가 제스처를 썼을 때, VoiceOver의 네이티브 API 혜택을 받도록 할 수 있는 것입니다. 정말 멋진 일 아닌가요?
지금은 Apple에서만 해당 기능을 발표했고, Android에선 지원하지 않지만, 미래에는 Android Talkback에서도 이 기능이 들어가길 바라며, Google에 꾸준히 건의할 예정입니다. 앞으로의 웹 접근성이 얼마나 발전할지 정말로 기대됩니다.
iOS 웹 접근성에 대한 소식은 여기까지이며, 좋은 소식을 전할 수 있게 되어 정말로 기쁩니다. 다음에는 더 기쁜 소식으로 찾아뵙겠습니다. 감사합니다.