
WAI-ARIA가 등장한 배경 및 동작 원리는 아래의 글 후반부에 정리해 두었다.
웹 표준과 웹 접근성
https://velog.io/@juwon98/Web-Standard
(Web Accessibility Initiative - Web Accessible Rich Internet Applications)
W3C의 WAI-ARIA 최신버전(1.2) 권고안
https://www.w3.org/TR/wai-aria/
접근성과 상호 운용성을 향상시키기 위한 WAI-ARIA는 역할(Role), 속성(Property), 상태(State) 3가지 기능을 제공한다.
특정 요소에 기능을 정의하는 것
<!-- 일반적인 a요소 -->
<a href="/">구매하기</a>
위의 코드는 구매하기 버튼을 a태그를 사용해서 만든 것이다.
하지만 브라우저는 이 a태그가 button이라는 역할을 하는지 알 수 없다.
그래서 스크린 리더 사용자는 '버튼'이 아니라 '링크'라고 듣기 때문에 문제가 생긴다.
<!-- button역할을 부여한 a요소 -->
<a role="button" href="/">구매하기</a>
이렇게 role="button"이라는 속성을 적어주면, 브라우저가 WAI-ARIA가 부여한 button이라는 역할로 인식하기 때문에 정상적으로 정보를 전달할 수 있게 된다.
WAI-ARIA 역할(Role)은 다음 4가지의 카테고리로 구분할 수 있다.
요소가 기본적으로 갖고 있는 특징이나 상황
폼의 입력 상자가 읽기 전용(Read Only) 인지 또는 필수 항목(Require)인지, 사용자 입력에 대해 자동 완성(Auto Complete)기능을 지원할 지 또는 드래그(Drag)가 가능한지, 팝업(has Popup)이 뜨는지, 업데이트된(Live) 정보가 있는지 등의 상황을 사용자가 인지할 수 있도록 할 수 있다.
요소의 현재 상태를 의미하며 상황의 변화에 따른 값
메뉴가 펼쳐진 상태(expanded)인지, 적절하지 못한(invalid) 값이 입력되었는지 콘텐츠가 숨김(hidden) 상태인지 등을 나타낼 수 있다.
ARIA의 역할, 속성, 상태 목록 및 사용법
MDN - ARIA
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA
HTML5에 새롭게 추가된 섹션 관련 요소의 경우 WAI-ARIA 규칙과 비슷한 역할의 요소가 다수 있다. 그러나 W3C 에서는 HTML5의 섹션 관련 요소와 WAI-ARIA 규칙을 함께 사용할 경우 해당 기능이 무효화 되거나 충돌이 발생할 수 있으므로 중복해서 사용하지 않도록 주의를 당부하고 있다.
랜드마크 Role과 HTML5 섹션 관련 요소 (semantic tag) 비교

랜드마크 사용 예시
HTML 마크업을 처음 공부할 때 레이아웃 구조를 비슷하게 그려본 적이 있어서 익숙한 느낌!

ARIA 규칙을 이용하여 요소의 네이티브(Native) 의미를 변경하는 것은 바람직하지 않다.
예를 들어 버튼의 역할을 하는 콘텐츠를 <h1> 요소로 마크업하고 role=“button”으로 지정하는 경우를 들 수 있다.
이미 제목이라는 의미가 있는 <h1> 요소에 직접 role 속성을 부여하기 보다 중립적인 의미를 가지는 <div> 요소나 <span> 등의 요소에 role=“button”을 부여하는 것을 권장한다.
<span role="button" tabindex="0">버튼</span>
사용자와 상호 작용이 필요한 대화형 UI의 경우 키보드로도 접근 및 사용이 가능하도록 제공해야 한다. 여기서 상호 작용이 필요한 대화형 UI란 사용자가 클릭할 수 있는 정보나 탭 또는 드래그 앤 드롭, 슬라이드, 스크롤 등의 기능이 필요한 콘텐츠를 의미합니다.
기본적으로 키보드로 접근할 수 없는 HTML 요소의 경우 tabindex 속성을 사용하여 키보드로 접근이 가능하도록 할 수 있다. tabindex 속성에 0을 지정하면 콘텐츠의 선형화 순서대로 접근할 수 있고 0보다 작은 값을 지정하면 키보드로 접근이 불가능 한 상태가 된다.
<!-- 키보드로 접근 가능 -->
<span role="button" tabindex="0">버튼</span>
<!-- 키보드로 접근 불가능 -->
<span role="button" tabindex="-1">버튼</span>
사용자에게 정보를 전달하되 단순히 화면에서만 보이지 않도록 처리된 콘텐츠에 aria-hidden=“true”를 지정해서는 안된다.
단순히 가시적으로만 숨긴 콘텐츠에 특정 role을 부여했더라도 스크린 리더 등의 보조 기기에서는 aria-hidden=“true”로 지정된 상태라면 의미적으로도 숨겨진 콘텐츠로 인식하게 된다.
스크린 리더 등의 보조 기기는 role=“presentation”, role=”none”으로 지정된 요소를 의미 없이 단순히 가시적으로 전달하기 위한 요소로 인식하기 때문에 특정한 의미를 전달해야 하는 요소에 presentation이나 none의 역할(Role)을 지정하여서도 안된다.
aria-hidden=“true”를 사용하여 숨김 콘텐츠에 대한 사용자의 접근을 차단하고자 할 경우 CSS의 display 속성에 none 값을 지정하여 스크린 리더 등의 보조기기에서 접근할 수 없도록 하고 aria-hidden=“true”을 명시해야 한다.
접근성을 지키면서 페이지를 구현해보다가 display: none, visibility: hidden 모두 스크린리더가 읽지 않는다는 것을 알고 text를 감추기 위한 많은 방법을 알아봤지만 문제가 너무 많았고, 아래의 블로그에서 관련 정보를 얻을 수 있었다.
https://mulder21c.io/screen-hide-text/
모든 대화형 UI의 경우 반드시 레이블을 제공하여야 합니다. 레이블 제공을 위해 HTML의 <label> 요소를 사용하는 것을 권장하며 WAI-ARIA 관련 속성으로 aria-label, aria-labelledby 등을 사용하여 접근 가능한 이름을 제공할 수도 있습니다.
<!-- 레이블 요소를 사용한 경우 -->
<div class="container">
<label for="user-name">이름</label>
<input type="text" id="user-name">
</div>
<!-- aria-label, aria-labelledby 속성을 사용한 경우 -->
<div>
<div id="user-name">이름</div>
<input type="text" aria-labelledby="user-name">
</div>
<!-- 닫기 버튼이라는 사실을 알 수 있게 aria-label 속성 사용 -->
<button aria-label="닫기"> X </button>
접근 가능한 이름 우선순위
1. aria-label
2. aria-labelledby
3. aria-describedby
4. title
title은 제공되는 접근가능한 이름이 없을 때 최후의 수단으로 읽는 정보이기 때문에 가급적이면 title이 아니라 aria-label을 사용하는 것이 좋음.
다만, title 속성이 마우스를 사용하는 User 입장에서 정보를 식별하기 용이한 방법일 수 있다면 aria-label과 함께 제공할 수도 있습니다.
https://www.w3.org/WAI/ARIA/apg/practices/names-and-descriptions/
WAI-ARIA를 사용할 경우 의미를 가지는 시맨틱 요소와 충돌되지 않도록 하는 것이 필요하다. 가령 헤딩의 의미를 가지는 <h1> 요소에 role=“button”을 부여하면 아래와 같이 해당 요소에 적절하지 않은 속성을 사용했다는 문법 오류가 발견된다.
