WAI-ARIA란?

정보 접근성과 상호 운용성을 위한 WAI-ARIA 소개


들어가며

회사에서 들었던 웹 접근성을 고려한 콘텐츠 제작 가이드 강의에서 웹 접근성 지침 준수는 모든 웹사이트의 의무사항이라고 들었습니다. 웹 접근성 마크를 취득해야 하는 프로젝트가 아니고서야 접근성 개선 작업은 많은 시간과 노력이 필요하기 때문에 굳이 작업하지는 않습니다. 작년에 진행한 프로젝트에서 웹 접근성 작업을 어떻게 해야 할지 고민하다 WAI-ARIA를 처음 접하고 경험하게 되었습니다.

언젠가부터 React, Vue, Angular와 같은 동적 콘텐츠를 제작하는 SPA 환경 프로젝트가 점차 많아지면서 WAI-ARIA는 사용자에게는 적절한 정보를 개발자에게는 편리하게 접근성을 높일 수 있는 기술이라 생각합니다. 복잡하고 동적으로 변화하는 웹 환경에서 신체적, 환경적 조건에 차별 없이 동등하게 이용할 수 있도록 도와주는 WAI-ARIA 기술에 대해 소개하고자 합니다.



WAI-ARIA란?

Web Accessibility Initiative – Accessible Rich Internet Applications
WAI 는 W3C에서 웹 접근성을 담당하는 기관으로 ARIA는 RIA 환경의 웹 접근성에 대한 표준 기술 규격을 의미

RIA : 정적인 HTML, 단순한 자바스크립트 환경의 웹이 아닌 동적인 자바스크립트와 Ajax와 같은 기술을 사용한 환경에서 수준 높은 UX(User eXperience)를 제공하는 웹 애플리케이션



WAI-ARIA를 사용하는 이유


  1. RIA의 동적 웹 애플리케이션 접근성 보장 지침이 부족
  2. Ajax, 통한 실시간 변경 콘텐츠, SPA 방식의 콘텐츠 변경
  3. 화면 확대사용자의 경우, 가시 범위 밖 콘텐츠의 변경 내용 인지 불가능

WAI-ARIA를 이용해서 개발자가 의도한 유저 인터페이스(User Interface) 행동이나 구조적인 정보를 스크린 리더와 같은 보조 기술에 전달하여 시각/인지 장애인들에게 일반 사용자들과 동일하게 정보를 제공하고 행동을 유도함으로써 웹페이지 탐색을 돕는 사용자 경험(UX)을 제공합니다.



WAI-ARIA 사용 하는 방법


ARIA는 HTML 태그에 필요한 정보를 제공해주는 보조 기술로서 아래의 내용을 주의하여 WAI-ARIA를 사용해주세요.


  1. HTML5 Section 요소와 중복되어 사용하지 말아 주세요.
    HTML5에서 추가된 의미 있는 태그를 먼저 사용하고 의미를 부가적으로 설명해주고자 할 때 WAI-ARIA의 role을 추가해줍니다.

HTML5 Section tag Landmark Role 설명
<nav> role="navigation" 다른 페이지 또는 페이지 내 특정 영역으로 이동하는 링크 콘텐츠 영역(메인 메뉴 혹은 서브 메뉴로 사용)
<main> role="main" 본문의 주요 콘텐츠 영역.
한 페이지 내에 1개만 사용이 가능하며,
<article>, <aside>, <footer> 요소의 하위 요소로 사용할 수 없다
<aside> role="complementary" 주요 콘텐츠와 연관이 적은 의미 있는 콘텐츠 영역 (예) 날씨, 주식
<form> role="form" 폼 요소로 서버에 전송될 수 있는 콘텐츠
X role="application" <div> 요소와 같이 그룹 역할을 하는 요소로 대체
X role="banner" <header> 요소와 비슷한 의미
<header role="banner">로 사용 시 페이지별 한 번만 사용
X role="search" 검색의 역할을 담당하는 서식 영역
<div> 또는 <form> 요소 사용 권장
X role="contentinfo" <footer> 요소와 비슷한 의미
<footer role="contentinfo">로 사용 시 페이지별 한 번만 사용



  1. 의미를 가진 HTML 요소를 함부로 바꾸지 말아 주세요.
<!-- X -->
<h1 role="button">PXD XE GROUP</h1>
<!-- △ -->
<h1><span role="button">PXD XE GROUP</span></h1>
<!-- ○ -->
<h1><button>PXD XE GROUP</button></h1>



  1. 키보드를 사용하여 접근할 수 있게 해주세요.

만약 <button>, <input> 요소들처럼 키보드 지원이 되는 요소를 <div>와 WAI-ARIA로 작업해야 한다면, 동일하게 작동되도록 작업해주세요.


<!-- html5 -->
<button>버튼<button>
</select>

<!-- div + WAI-ARIA -->
<div role="button" tabindex="0">버튼</div>



  1. 사용자의 브라우저와 보조기기가 WAI-ARIA를 지원하는지 확인해주세요.

WAI-ARIA는 우리가 사용하는 크롬, 인터넷 익스플로어, 사파리 등의 최신 버전 브라우저들은 대체로 지원을 합니다. 아래의 이미지는 Can I Use에서 확인한 WAI-ARIA의 지원 범위를 보여줍니다.


ariaCrossBrower
WAI-ARIA 지원 브라우저 현황 (출처 : https://caniuse.com/?search=wai-aria)


Ajax 등을 이용해 콘텐츠가 동적으로 변경되는 요소에 사용되는 aria-live 속성을 대표적으로 알아보면 스크린 리더기 JAWS(JAWS for Windows)는 version 10.0, Windows Eyes는 version 8.0부터 사용 가능합니다.

ariaLiveCrossBrower
MDN 사이트 aria-live 속성
(출처 : https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions)



WAI-ARIA 구조

WAI-ARIA를 구성하는 역할, 속성, 상태 기능은 HTML 요소에 보충하여 사용됩니다.

1. 역할(Role) : 컴포넌트, 요소 내 역할을 정의 우리는 대체로 눈으로 인지하고 학습해온 경험으로 아래의 이미지를 봤을 때 ‘탭 버튼이구나! 버튼을 누르면 아래의 콘텐츠는 변경이 되겠지’라고 생각 할 수 있습니다.


tabArea
탭 영역 (출처 : https://tour.president.go.kr/tours/about/)

개발자는 탭 버튼을 작업할 때 단순히 <ul>, <li>, <a> 태그로 탭을 구성합니다.
WAI-ARIA role=“tabList”, role=“tab” role=“tabpanel” 로 스크린 리더기 사용자에게 더 정확한 정보를 제공할 수 있습니다.


<!-- 일반적인 작업 -->
<ul class="btnList">
  <li>
    <a href="#" class="on">관람정보</a>
  </li>
  <li>
    <a href="#">관람순서</a>
  </li>
  <li>
    <a href="#">장애인 관람객 이용안내</a>
  </li>
</ul>

<div class="wrap-tab-contents">
  <div id="tabpanel01" class="tab-contents on"><p>관람정보 콘텐츠</p></div>
  <div id="tabpanel02" class="tab-contents"><p>관람순서 콘텐츠</p></div>
  <div id="tabpanel03" class="tab-contents"><p>장애인 관람객 이용안내 콘텐츠</p></div>
</div>

<!-- WAI-ARIA 적용 -->
<ul class="btnList" role="tabList">
  <li>
    <a
      href="#"
      id="tab01"
      class="on"
      role="tab"
      aria-selected="true"
      aria-controls="tabpanel01"
      >관람정보</a
    >
  </li>
  <li>
    <a href="#" id="tab02" role="tab" aria-selected="false" aria-controls="tabpanel02"
      >관람순서</a
    >
  </li>
  <li>
    <a href="#" id="tab03" role="tab" aria-selected="false" aria-controls="tabpanel03"
      >장애인 관람객 이용안내</a
    >
  </li>
</ul>

<div class="wrap-tab-contents">
  <div
    id="tabpanel01"
    class="tab-contents"
    role="tabpanel"
    aria-labelledby="tab01"
    tabindex="0"
  >
    <p>관람정보 콘텐츠</p>
  </div>
  <div
    id="tabpanel01"
    class="tab-contents"
    role="tabpanel"
    aria-labelledby="tab02"
    tabindex="0"
    hidden="true"
  >
    <p>관람순서 콘텐츠</p>
  </div>
  <div
    id="tabpanel01"
    class="tab-contents"
    role="tabpanel"
    aria-labelledby="tab03"
    tabindex="0"
    hidden="true"
  >
    <p>장애인 관람객 이용안내 콘텐츠</p>
  </div>
</div>

위 코드를 NVDA(NonVisual Desktop Access)라는 스크린 리더기 프로그램으로 들어보면 의미가 다르게 전달 되는 것을 알 수 있습니다.


  1. 탭 메뉴 WAI-ARIA 적용 전

-> 페이지를 이동하는 “링크” 태그로서의 의미만을 정보만 전달해주다.

  1. 탭 메뉴 WAI-ARIA 적용 후

-> 버튼의 역할이 “탭”이라고 명시해주고, 선택된 요소 정보도 함께 전달해줄 수 있다.



2. 속성(Property) : 컴포넌트의 특징이나 상황을 정의

폼 요소의 필수 요소와 관련된 속성인 aria-required, 텍스트 레이블이 없이 이미지로 표현될 때 정보를 부여 설명해주는 aria-label, 업데이트된 정보의 상황에 대한 aria-live와 같이 사용자에게 인지 할 수 있도록 도와주는 속성들이 있습니다.


searchArea
검색 버튼 (출처 : https://story.pxd.co.kr/)

검색이라는 안내 텍스트 없이 버튼을 나타낼 때 시각 정보를 이용할 수 없는 사용자는 어떤 버튼인지 알 수 없습니다. 물론 우리는 대체 텍스트를 이용할 수 있지만, aria-label을 이용하여 버튼 요소에 검색이라는 설명을 추가할 수 있습니다.


<button class="btn_search"></button>

<!-- 숨김 텍스트 이용 -->
<button class="btn_search">
  <span class="hidden">검색</span>
</button>
<!-- WAI-ARIA 적용 -->
<button class="btn_search" aria-label="검색"></button>



3. 상태(State) : 컴포넌트 상태 정보를 정의

메뉴의 활성 여부를 보여주는 aria-expanded, aria-selected, 폼 요소 유효성 검증과 관련 있는 aria-invalid와 같이 현재 상태와 변화된 값을 가집니다.
상태가 변화될 때 확장됨 / 축소됨, 눌림 / 눌리지 않음 으로 음성으로 알려주며, aria-invalid 상태에 따라 에러 텍스트를 노출함으로써 사용성을 높여줄 수 있다. 흔히 사용되는 탭, 아코디언, 폼 요소, 토글버튼 등 상태 값을 이용하여 Javascript 기능을 만듭니다.



accordionArea
아코디언 예제 (출처 : http://pxd.co.kr/pages/jobs/jobs_main.html)

아코디언 메뉴의 활성 상태 값인 aria-expanded를 이용하면 스크린 리더기가 상태 정보(확장됨 or 축소됨)를 읽어 줄 수 있습니다.
javascript로 기능을 정의할 때 상태 값(aria-expanded)을 통해 작성할 수 있고 또한 css 처리를 위한 .open 클래스 바인딩을 하지 않아도 됩니다.


<ul class="btnList">
  <li class="open">
    <button>[XD그룹] UI 기획 디자이너 (경력)</button>
    <div>[XD그룹] UI 기획 디자이너 (경력) 콘텐츠</div>
  </li>
  <li>
    <button>[XE그룹] UX Engineer (신입/경력)</button>
    <div>[XE그룹] UX Engineer (신입/경력) 콘텐츠</div>
  </li>
  <li>
    <button>인턴 디자이너</button>
    <div>인턴 디자이너 콘텐츠</div>
  </li>
</ul>
<style>
  li {
    background-image: url(arrow_down.png);
  }
  li.open {
    background-image: url(arrow_up.png);
  }
</style>

<!-- WAI-ARIA 적용 -->
<ul class="btnList">
  <li>
    <button id="accordion-head01" aria-controls="accordion-region01" aria-expanded="true">
      [XD그룹] UI 기획 디자이너 (경력)
    </button>
    <div id="accordion-region01" role="region" aria-labelledby="accordion-head01">
      [XD그룹] UI 기획 디자이너 (경력) 콘텐츠
    </div>
  </li>
  <li>
    <button id="accordion-head02" aria-controls="accordion-region02">
      [XE그룹] UX Engineer (신입/경력)
    </button>
    <div id="accordion-region02" role="region" aria-labelledby="accordion-head02">
      [XE그룹] UX Engineer (신입/경력) 콘텐츠
    </div>
  </li>
  <li>
    <button id="accordion-head03" aria-controls="accordion-region03">
      인턴 디자이너
    </button>
    <div id="accordion-region03" role="region" aria-labelledby="accordion-head03">
      [XD그룹] 인턴 디자이너 콘텐츠
    </div>
  </li>
</ul>
<style>
  li {
    background-image: url(arrow_down.png);
  }
  li button[aria-expanded='true'] {
    background-image: url(arrow_up.png);
  }
</style>

  1. 아코디언 메뉴 WAI-ARIA 적용 전

-> 아코디언 버튼 메뉴가 활성화/비활성화 상태에 대한 정보를 알 수가 없다.

  1. 아코디언 메뉴 WAI-ARIA 적용 후

-> 아코디언 버튼 메뉴가 활성화됐을 경우, “확장됨, 축소됨”으로 상태 정보를 전달해줄 수 있다.


위에 소개된 역할, 속성, 상태의 다양한 값들은 아래의 링크로 자세히 알아볼 수 있습니다.

ARIA 구성 요소 더 알아보기



마치며

현재 그룹 블로그 내 이슬비 책임님이 웹 접근성을 준수하는 코드 작성하기 시리즈를 포스팅 중인데 WAI-ARIA에 대한 이해도를 높이고 읽으면 더 좋지 않을까 싶어요.

이번 포스팅이 WAI-ARIA에 대한 이해와 실제 코드를 읽을 때 조금이라도 도움이 되었길 바랍니다.

감사합니다.

참고문서