: 웹 사이트에서 제공하는 정보에 장애인, 고령자 등이 비장애인과 동등하게 접근하고 이해할 수 있도록 보장하는 것
아래의 지침은 W3C의 웹 접근성 권고안 "WCAG(Web Content Accessibility Guidelines) 2.0"을 기반으로 한국에 맞게 수정한 "한국형 웹 콘텐츠 접근성 지침 2.1"을 정리한 것이다.
모든 콘텐츠는 사용자가 인식할 수 있어야 한다.
: 텍스트가 아닌 콘텐츠는 그 의미나 용도를 이해할 수 있도록 대체 텍스트를 제공해야 한다.
<img src={catImage} alt='윙크하는 고양이' />
<img src={background} alt='' />
<img src={redPandaImage} alt='' />
<p>래서 펜더가 대나무를 앞발로 잡고 혀를 내밀고 있다.</p>
: 멀티미디어 콘텐츠에는 자막, 원고, 또는 수화를 제공해야 한다.
video
요소 안에 track
요소를 사용하여 자막 파일 불러오기<video ... >
<track src="자막.vtt" kind="cation"/>
</video>
: 콘텐츠는 색에 관계 없이 인식될 수 있어야 한다.
: 지시사항은 모양, 크기, 위치, 방향, 색, 소리 등에 관계없이 인식될 수 있어야 한다.
: 텍스트 콘텐츠와 배경 간의 명도 대비는 4.5 : 1 이상이어야 한다.
다음 상황에서는 콘텐츠와 배경 간의 명도 대비가 3 : 1 까지 허용된다.
: 동영상, 오디오, 음성, 배경 음악 등 모든 종류의 소리가 자동으로 재생되지 않아야한다.
: 이웃한 콘텐츠는 구별될 수 있어야 한다.
사용자 인터페이스 구성 요소는 조작 가능하고 내비게이션할 수 있어야 한다.
: 모든 기능은 키보드만으로도 사용할 수 있어야 한다.
: 키보드에 의한 초점은 논리적으로 이동해야 하며 시각적으로 구별할 수 있어야 한다.
: 사용자 입력 및 컨트롤은 조작 가능하도록 제공되어야 한다.
: 가급적이면 시간 제한이 있는 콘텐츠를 넣지 않는 게 좋지만, 보안 등의 사유로 넣어야한다면, 응답 시간을 조절할 수 있어야 한다.
① 충분한 시간을 제공한다.
② 종료까지 남은 시간을 알려준다.
③ 조절 수단을 제공해야 한다. (시간 연장, 로그아웃 등)
: 자동으로 변경되는 콘텐츠는 움직임을 제어할 수 있어야 한다.
: 초당 3~50회 주기로 깜빡이거나 번쩍이는 콘텐츠를 제공하지 않아야 한다.
: 콘텐츠의 반복되는 영역은 건너뛸 수 있어야 한다.
스크린 리더를 사용하는 경우, 헤더나 네비게이션 바와 같이 모든 페이지에서 반복되는 요소들을 반복해서 읽어준다. 따라서 이러한 요소들을 건너뛰고 메인 콘텐츠로 이동할 수 있는 방법을 제공해야 한다.
: 페이지, 프레임, 콘텐츠 블록에는 적절한 제목을 제공해야 한다.
: 링크 텍스트는 용도나 목적을 이해할 수 있도록 제공해야 한다.
콘텐츠는 이해할 수 있어야 한다.
: 주로 사용하는 언어를 명시해야 한다.
html
요소에 lang
속성을 이용해 명시한다.<html lang="ko">
...
</html>
lang
속성을 표기한다.: 사용자가 의도하지 않은 기능은 실행되지 않아야 한다. (ex. 새 창, 초점에 의한 맥락 변화)
<!-- 1. 링크 요소 안에 보이지 않는 요소를 넣어 새 창에 접근하게 됨을 알려주기 -->
<a href="...com">페이지</a> ❌
<a href="...com">페이지<span class="invisible">새 창</span></a> ⭕️
<!-- 2. 링크 요소의 title 속성에 새 창 작성하기 -->
<a href="...com" title="새 창">페이지</a> ⭕️
<!-- 3. 링크 요소에 target="_blank" 속성 넣기 -->
<a href="...com" target="_blank">페이지</a> ⭕️
: 콘텐츠는 논리적인 순서로 제공해야 한다.
<!-- 아래처럼 작성할 경우, 스크린 리더는 탭1 → 탭2 → 탭1 내용 → 탭2 내용 순서로 읽는다.-->
<div>탭1</div>
<div>탭2</div>
<div>탭1 관련 내용</div>
<div>탭2 관련 내용</div> ❌
<!-- 아래처럼 작성할 경우, 스크린 리더는 탭1 → 탭1 내용 → 탭2 → 탭2 내용 순서로 읽는다.-->
<div>탭1</div>
<div>탭1 관련 내용</div>
<div>탭2</div>
<div>탭2 관련 내용</div> ⭕️
: 표는 이해하기 쉽게 구성해야 한다.
시각 장애가 있는 경우에는 내용을 들으면서 표를 파악해야 하므로, 듣기만해도 표의 구조와 내용을 이해하기 쉽게 구성해야 한다.
테이블 요소 안에 <caption>
요소를 사용해서 표의 제목 제공하기
제목 셀에는 <th>
요소, 데이터 셀에는 <td>
요소를 사용해 제목 셀과 데이터 셀이 구분되도록 구성하기
제목 1 | 제목 2 |
---|---|
내용 1 | 내용 2 |
내용 3 | 내용 4 |
<table>
<caption>테이블 제목</caption> // 제목
<thead> // table head : 제목 셀
<tr>
<th>제목 1</th>
<th>제목 2</th>
<tr>
</thead>
<tbody> // table body : 내용 셀
<tr>
<td>내용 1</td>
<td>내용 2</td>
</tr>
</tbody>
</table>
scope
속성 사용하기이름 | 열 제목 1 | 열 제목 2 | 열 제목 3 |
---|---|---|---|
행 제목 1 | 내용 1 | 내용 2 | 내용 3 |
행 제목 2 | 내용 1 | 내용 2 | 내용 3 |
행 제목 3 | 내용 1 | 내용 2 | 내용 3 |
<table>
<caption>테이블 제목</caption>
<thead>
<tr>
<th scope='col'>이름</th>
<th scope='col'>열 제목 1</th>
<th scope='col'>열 제목 2</th>
<th scope='col'>열 제목 3</th>
<tr>
</thead>
<tbody>
<tr>
<td scope='row'>행 제목 1</td>
<td>내용 1</td>
<td>내용 2</td>
<td>내용 3</td>
</tr>
<tr>
<td scope='row'>행 제목 2</td>
...
</tr>
<tr>
<td scope='row'>행 제목 3</td>
...
</tr>
</tbody>
</table>
id
, headers
속성 사용하기이름 | 열 제목 1 | 열 제목 2 | 열 제목 3 |
---|---|---|---|
행 제목 1 | 내용 1 | 내용 2 | 내용 3 |
행 제목 2 | 내용 1 | 내용 2 | 내용 3 |
행 제목 3 | 내용 1 | 내용 2 | 내용 3 |
<table>
<caption>테이블 제목</caption>
<thead>
<tr>
<th id='이름'>이름</th>
<th id='열 제목 1'>열 제목 1</th>
<th id='열 제목 2'>열 제목 2</th>
<th id='열 제목 3'>열 제목 3</th>
<tr>
</thead>
<tbody>
<tr>
<td id='행 제목 1'>행 제목 1</td>
<td headers='열 제목 1 행 제목 1'>내용 1</td>
<td headers='열 제목 2 행 제목 1'>내용 2</td>
<td headers='열 제목 3 행 제목 1'>내용 3</td>
</tr>
<tr>
...
</tr>
<tr>
...
</tr>
</tbody>
</table>
: 사용자 입력에 대응하는 레이블을 제공해야 한다.
사용자가 <input>
요소에 어떤 정보를 입력해야 하는지 정확하게 알 수 있도록 <label>
요소를 이용해 레이블을 제공해야 한다.
<!-- input 요소에 value나, placeholder 속성만 설정하는 것은 부족하다. -->
<input type="text" placeholder="아이디" /> ❌
<!-- input 요소에 id, label 요소에 htmlFor 속성을 이용해 둘을 연결해준다. -->
<label htmlFor="user_id">아이디</label>
<input id="user_id" type="text" placeholder="아이디" /> ⭕️
<!-- input 요소에 title 속성을 사용한다. -->
<input title="아이디" type="text" placeholder="아이디" /> ⭕️
<!-- WAI-ARIA의 aria-label 속성을 사용한다. -->
<input aria-label="아이디" type="text" placeholder="아이디" /> ⭕️
: 입력 오류를 정정할 수 있는 방법을 제공해야 한다.
웹 콘텐츠를 미래의 기술로도 접근할 수 있도록 견고하게 만들어야 한다.
: 마크업 언어의 요소는 열고 닫음, 중첩 관계, 속성 선언에 오류가 없어야 한다.
<!-- 열고 닫음의 오류 -->
<div><span></div></span>
<!-- 속성 중복 사용 -->
<div class="중복" class="사용"></div>
<!-- id 중복 사용 -->
<div id="special-id">
<span id="special-id"></span>
</div>
: 콘텐츠에 포함된 웹 애플리케이션을 접근성이 있어야 한다.
웹 콘텐츠에 포함된 웹 애플리케이션도 접근성을 갖춰야 한다.
접근성을 갖추지 못한 경우에는 대체 수단이나 대체 텍스트를 제공해야 한다.
: 웹 표준을 정하는 W3C에서 웹 접근성을 담당하는 기관
: 장애가 있는 사람들이 웹 콘텐츠와 웹 응용 프로그램에 더 쉽게 액세스할 수 있도록 하는, 즉 웹 접근성을 갖추기 위한 기술
RIA (Rich Internet Applications)
: 따로 프로그램을 설치하지 않아도 ① 웹 브라우저를 통해 사용할 수 있는 편리성, ② 프로그램을 직접 설치해서 사용하는 것처럼 빠른 반응의 사용자 인터페이스를 가지는 웹 애플리케이션
SPA(Single Page Application)를 의미하는 경우가 많다.
➡️ 즉, WAI-ARIA는 WAI에서 발표한, RIA 환경에서의 웹 접근성 기술 규격을 말한다.
시맨틱 요소만으로 의미를 충분히 부여할 수 없는 상황에서 WAI-ARIA를 사용하면, HTML 요소에 추가적인 의미를 부여할 수 있다. (시맨틱 요소만으로 충분한 상황에서는 사용하지 X)
➡️ 사용자가 좀 더 원활하게 페이지를 탐색할 수 있도록 돕는다.
SPA처럼 AJAX를 사용하는 상황, 즉 새로고침 없이 페이지의 내용이 바뀌는 상황에서도 변경된 영역에 대한 정보를 전달해줄 수 있다.
➡️ 동적인 콘텐츠에서도 웹 접근성을 향상시킬 수 있다.
WAI-ARIA는 HTML 태그 내부에 속성(attribute)을 추가함으로써 의미를 부여할 수 있으며, 속성은 크게 3가지로 나뉜다.
: HTML 요소의 종류와 역할이 맞지 않을 때, 어떤 역할을 하는 요소인지 명시해줄 때 사용하는 속성
WAI-ARIA Roles - MDN
주의할 점
- HTML 요소로 이미 파악할 수 있는 내용을 WAI-ARIA로 재설명하지 않는다.
<button role="button">Click Me!</button> ❌
- 시맨틱 요소의 본연의 의미를 임의로 바꾸지 말아야 한다.
<h1 role="button">Title</h1> ❌
button role
<div role="button">Click Me!</div> // button의 역할을 하는 div 요소
tablist role
& tab role
: 여러 개의 탭 버튼을 감싸는 컨테이너 & 탭 버튼
<div role="tablist"> // tabList 역할을 하는 div 요소
<li role="tab">Tab1</li> // tab 역할을 하는 li 요소
<li role="tab">Tab2</li>
<li role="tab">Tab3</li>
</div>
tabpanel role
: 탭의 콘텐츠(내용)을 나타내는 탭 패널
<div role="tabpanel">Tab menu ONE</div> // tab panel 역할을 하는 div 요소
<div role="tabpanel">Tab menu TWO</div>
<div role="tabpanel">Tab menu THREE</div>
ARIA states and properties - MDN
aria-selected
: 여러 개의 선택 가능한 요소 중에서 선택 상태인 요소를 표시할 수 있는 속성
선택된 요소는 true
, 선택되지 않은 요소는 false
값을 지정한다.
<div role="tabList">
<li role="tab" aria-selected="true">Tab1</li> // 선택된 요소
<li role="tab" aria-selected="false">Tab2</li>
<li role="tab" aria-selected="false">Tab3</li>
</div>
<div role="tabpanel">Tab menu ONE</div>
<div role="tabpanel">Tab menu TWO</div>
<div role="tabpanel">Tab menu THREE</div>
aria-expanded
: menu, dialog, accordion 등의 UI가 펼쳐진 상태인지 표시할 수 있는 속성
<button id="hamburger" aria-expanded="false"></button>
aria-hidden
: aria-hidden
속성에 true
속성값을 가진 요소는 스크린 리더로부터 숨겨진다.
<button>
<span class="fa fa-tweet" aria-hidden="true"></span> // 아이콘
<span>Tweet</span>
</button>
aria-label
: 요소에 라벨을 붙여주는 속성으로, 스크린 리더는 aria-label
의 속성값을 읽어준다.
아래 예시처럼 버튼에 이미지만 들어있는 버튼의 경우, HTML 요소의 구조만으로는 어떤 역할을 하는 버튼인지 파악할 수 없으므로, aria-label
속성으로 의미를 부여해준다.
<button aria-label="닫기 버튼"/> <img src="X.png" /> </button>
<button aria-label="검색 버튼"/> <img src="돋보기.png" /> </button>
aria-live
: 실시간으로 내용을 갱신하는 영역에 사용하여 갱신된 내용을 읽어주는 속성
브라우징 도중에 내용을 띄우는 alert
, modal
, dialog
와 같은 역할을 하는 요소거나, AJAX 기술을 사용하여 실시간으로 내용을 갱신하는 영역에 사용한다.
off
(default) : 스크린 리더가 갱신된 내용이 있어도 읽지 않는다.polite
: 스크린 리더가 현재 읽고 있는 내용을 모두 읽고 나서 갱신된 내용을 사용자에게 전달한다.assertive
: 스크린 리더가 현재 읽고 있는 내용을 중단하고 갱신된 내용을 사용자에게 전달한다.<div class="alertbar" aria-live="assertive">
Could not connect!
</div>
Using ARIA: Roles, states, and properties - MDN
ARIA in HTML - W3C