WAI-ARIA 웹접근성을 위해선 빠질 수 없다

2
post-thumbnail

🎀 WAI-ARIA란?

  • Web Accessibility Initiative – Accessible Rich Internet Applications + RIA
    RIA : 정적인 HTML, 단순한 자바스크립트 환경의 웹이 아닌 동적인 자바스크립트와 Ajax와 같은 기술을 사용한 환경에서 수준 높은 UX(User eXperience)를 제공하는 웹 애플리케이션을 의미한다.
  • WAI-ARIA를 이용해서 개발자가 의도한 유저 인터페이스(User Interface) 행동이나 구조적인 정보를 스크린 리더와 같은 보조 기술에 전달하여 시각/인지 장애인들에게 일반 사용자들과 동일하게 정보를 제공하고 행동을 유도함으로써 웹페이지 탐색을 돕는 사용자 경험(UX)을 제공한다.

쉽게 말해서 검색 엔진에 노출이 잘 되도록 하고, 장애인, 비장애인 할 것 없이 최적의 웹 서비스를 받아볼 수 있도록 구현하는 것을 말한다.

🎀 Role (역할)

  • 태그의 역할을 알려주는 속성이다.
  • 정해진 role 값을 넣어주어야한다. Role의 종류는 ❗️여기를 눌러서 확인해 보자.
<!-- 단순히 li, div로 표현하던 요소의 역할을 알려준다. -->
<li role="menuitem">tab</li>

<!-- link 이동을 시켜주는 버튼이지만 role을 지정하여 스크린 리더에서는 버튼으로 이해시킨다. -->
<a href="#" role="button">submit</a>

🎀 Role, 이것만은 주의하세요

첫번째, HTML 특정 태그와 중복되지 않도록 한다.

<!-- 잘못된 예시 -->
<button role="button"></button>

<!-- 제안 -->
<a href="#" role="button"></a>

두번째, HTML 시멘틱 태그에 role은 추가하지 않는다.

<!-- 잘못된 예시 -->
<nav role="button"></nav>

<!-- 제안 -->
<nav><button></button></nav>

세번째, 키보드로 제어할 수 있어야 한다.

  • 만약 role="button"이라면 tab으로 focus한 다음 enter키를 눌렀을 때 실행되어야 한다.
  • 사용자가 상호작용해야하는 요소라면 tabindex를 쓸것을 추천한다.

<!-- tab키 누르면 input에만 포커스 된다. -->
<h2>로그인</h2>
<label>
  <span>이름: </span>
  <input type="text" name="name" />
</label>

<!-- tabindex 0 : h2에도 포커스 된다. -->
<h2 tabindex="0">로그인</h2>
<label>
  <span>이름: </span>
  <input type="text" name="name" />
</label>

<!-- tab키 누르면 span도 포커스 된다. -->
<span tabindex="0" role="button">제출</span>

<!-- tabindex -1 : input의 포커스를 건너뛴다. -->
<h2 tabindex="0">로그인</h2>
<label>
  <span>이름: </span>
  <input tabindex="-1" type="text" name="name" />
</label>

🎀 이렇게 써보자

  1. role=”button”

    tab으로 접근하지 못하는 p, span, div 에서 사용 가능하다.
    하지만 <button>, <input type=”button”>, <input type=”submit”>에서 사용할 것을 권장한다.

  2. role=”search”

    <div>또는 <form>에 사용 권장.

  3. role=”navigation”

    <nav>와 동일한 의미를 가진다.

  4. role=”main”

    <main>과 동일한 의미를 가진다. 한페이지에 1개 사용 권장.

  5. role=”contentinfo”

    <footer>와 비슷한 의미를 가진다. 한페이지에 1개 사용 권장.

  6. role=”banner”

    <header>와 비슷한 의미를 가진다. 한페이지에 1개 사용 권장.

  7. role=”tablist”

    탭의 리스트로 인식하도록 한다.

    <ul class="tab-wrap" role="tablist">
    	...
    </ul>
  8. role=”tab”

    탭 리스트의 내부 요소를 의미한다.

    <ul class="tab-wrap" role="tablist">
    	<li class="tab-item" role="tab">탭01</li>
    	<li class="tab-item" role="tab">탭02</li>
    	<li class="tab-item" role="tab">탭03</li>
    </ul>
  9. role=”none” / role=”presentation”

    시멘틱 태그의 의미를 해당 태그와 자식 요소로부터 제거하는 역할.
    HTML 의미에 맞지 않게 마크업한 경우, 스타일링에 필요한 마크업을 추가한 경우 사용할 수 있다.

    <ul role="tablist">
    	<li role="none">
    		<a href="#" role="tab">tab01</a>
    	</li>
    	<li role="none">
    		<a href="#" role="tab">tab02</a>
    	</li>
    	<li role="none">
    		<a href="#" role="tab">tab03</a>
    	</li>
    </ul>
  10. role="alert"
    사용자에게 바로 전달되어야하는 중요한 알림/오류 메시지를 전달한다.
    aria-live="asserive"와 같은 역할을 하기 때문에 동시에 두개를 선언해줄 필요는 없다.

    <p role="alert">이메일 정보가 틀립니다. 다시 확인해 주세요.</p>
    <p aria-live="asserive">이메일 정보가 틀립니다. 다시 확인해 주세요.</p>
  11. role=”group”

    radio 버튼 따위의 그룹화를 스크린 리더는 잘 인식하지 못한다. 이런 문제를 해결할 때 사용할 수 있다.

    <div id="classtxt">Cabin Class</div>
    <ul role="group" aria-labelledby="classtxt">
        <li>
            <input id="economy" type="radio" value="economy" 
             checked="checked" name="cabin">
            <label for="economy">Economy Class</label>
        </li>
        <li>
            <input id="Prestige " type="radio" value="Prestige" name="cabin">
            <label for="Prestige ">Prestige Class</label>
        </li>
        <li>
            <input id="First" type="radio" value="First" name="cabin">
            <label for="First">First Class</label>
        </li>
    </ul>

    위와 같이 묶어줄 경우 스크린리더로 아래와 같이 들린다.

    Cabin Class 그룹
    라디오버튼 선택됨
    Economy Class 1/3

    라디오버튼만 그룹이 되는 것이 아니고, 생년월일이 따로 입력해야 할 때도 나뉘어져 있는 입력박스는 그루핑이 되어야 하고 그룹명이 필요하다.

    자료 출처 : https://aoa.gitbook.io/skymimo/improve/group

  12. aria-hidden
    aria-hidden의 사용으로 불필요한 정보를 스크린 리더가 읽지 못하도록 설정하여 사용자의 이해를 돕는다.
    혹은 반대로, 웹 상에는 시각적으로 보이지 않아야 하지만 스크린 리더 사용자에게는 보여야 하는 경우도 컨트롤 가능하다.

  • aria-hidden="true" 보조 기기 사용자에게는 이 요소 내용이 읽히지 않음

    <div aria-hidden="true">
    <p>모달 창 안의 콘텐츠</p>
    <button>닫기</button>
    </div>
  • aria-hidden="false" 보조 기기 사용자에게는 읽혀진다.
    css로 visibility:hidden; display:none;은 시각적으로도 보이지 않고 스크린 리더로도 읽히지 않는데, 이때 false 값을 주면 스크린 리더가 읽게된다.

    <div aria-hidden="false">
    <p>모달 창 안의 콘텐츠</p>
    <button>닫기</button>
    </div>
  1. aria-label
    aria-label은 사용자에게 역할을 알려준다는 점에서 role과 유사하다. 하지만 role은 마치 시멘틱 태그처럼 그 역할이 정해져있는 반면에 label은 스크린 리더 사용자에게 직접적으로 그 역할을 설명해 주어야한다.
    예) aria-label="섹션 이동 탭"
    ❗️시멘틱 태그에서는 role 없어도 사용 가능하지만, 의미없는 요소 <div>,span,p 등에는 role이 없으면 사용하면 안된다.

    <div>
      <a href="#" aria-label="펼치기" role="button"><i class="ico ico-arrow"></i></a>
    </div>

    위와 같이 입력해 주면, a 태그로 링크가 이동된다는것이 아니라,
    role의 사용으로 버튼임을 알리고, label로 펼쳐진다는 것도 알려줄 수 있다.

  2. aria-labelledby
    특정 요소나 그룹의 설명 텍스트가 있는 경우, 해당 텍스트의 id와 그룹을 묶어주는 역할을 한다.

    <button aria-label="Blue" aria-labelledby="color">Red</button>
    <span id="color">Yellow</span>
  3. aria-haspopup

    <button aria-haspopup='true'>거절하기</button>

    true 값을 지정해주면 스크린 리더기가 아래와 같이 읽어준다.

    거절하기 팝업 버튼

  4. role='dialog' + aria-modal='true'
    모달 컨텐츠에 사용된다.

    <div class='modal-container' aria-labelledby='modla-title' role='dialog' aria-modal='true'>
        <h2 id='modla-title'>모달입니다.</h2>
    </div>



📌 더 많은 정보는 여기서 확인해 보자.

profile
일단 해. 그리고 잘 되면 잘 된 거, 잘 못되면 그냥 해본 거!

0개의 댓글