해당 글은 우아한테크코스에서 진행한 테크니컬 라이팅을 위해 작성한 글입니다. 본문의 글에 추가적인 내용들을 추가하여 업로드 합니다.
💡 읽기 전! 이런 분들에게 추천해요.
- 웹 접근성에 대해 들어본 적이 있으나 잘 모르시는 분
- 스크린리더에 대해 들어본 적이 있으나 잘 모르시는 분
- WAI-ARIA에 대해 기초적인 지식이 필요하신 분
본격적으로 글을 시작하기에 앞서 내가 왜 스크린 리더를 주제로 글을 작성하게 되었는지 설명하고 한다.
스크린 리더를 주제로 글을 작성하게 된 이유
우테코에서 테크니컬 라이팅 작성을 위해 주제를 오래 고민하고 있었다. 그러던 중 한 영상을 보게 되었다.
직접 시각 장애인분이 어떻게 스마트폰을 사용하는지 iOS의 voice over를 사용하시는 모습이 담긴 영상이었다. 이 영상을 보면서 나에게는 새로운 시각이 트이게 되었다. 그동안에는 시각 장애를 가졌다면 스마트 기기를 원활하게 사용하지 못할 것이라고 생각하고 있었다. 그러나 오히려 반대였다. 스마트폰에서는 장애를 가졌던 가지지 않았던 모두가 평등했다. 이는 기기가 이런 차별을 없애기 위해 노력해서 만든 결과물이었다.
스마트 기기들은 장애를 차별하지 않기 위해 정말 정교한 부분들을 배려하며 만들어져있었다. 내가 그간 겪은 적이 없기 때문에 몰랐던 것이다. 그런데 기기가 차별하지 않는데 웹 서비스들이 사람을 차별한다면? 결국은 해당 서비스는 사용되지 못할 것이다.
이것은 사용자를 놓친다는 개념보다는 개발자가 서비스를 만들 때, 의도하지 않게 사람을 차별할 수도 있다고 느꼈다. 나도 모르게 시각 장애인들을 차별해왔던 것이다.
그래서 행동대장 서비스를 voice over를 활용하여 사용해봤다. 내가 개발한 목적대로 절대 사용할 수가 없었다. 그래서 나는 내가 만든 서비스라도 모두가 평등할 수 있도록 하고 싶다.
웹 접근성에는 스크린 리더 뿐 만 아니라 정말 다양한 요소를 고려해야 하지만, 차근 차근 일단은 스크린 리더에 관한 것 부터 개선해 보자는 생각이 들었다. 그래서 이번 테크니컬 라이팅의 주제로 웹 접근성 중 스크린 리더를 개선하기 위해 사용되는 WAI-ARIA를 중점으로 내용을 작성했다.
웹 접근성 - 스크린 리더: 모든 사용자를 위한 평등한 디지털 환경
지난 2021년 코로나19의 장기화로 인해 온라인 쇼핑이 트렌드가 되었다. 그러나 시각장애인 A씨는 온라인 쇼핑을 사용할 수 없었다. ‘스크린 리더’ 를 사용하여 온라인 쇼핑을 진행하려 했으나 대체 텍스트가 제대로 입력되어 있지 않았다. 스크린 리더는 그저 ‘이미지’라는 말만 반복했다.
시각장애인 B씨 또한 비슷한 불편함을 겪었다. 국세청 홈택스를 통해 집에서 편하게 납세하고 싶었다. 그러나 ‘스크린 리더’를 사용했을 때, 정확한 명칭이 아닌 엉뚱한 설명이 나왔다. 이로 인해 B씨는 홈택스를 통한 납세가 어려웠다. 이렇게 시각장애인 A와 B씨는 온라인 서비스를 제대로 이용할 수 없었다. 왜 이런 일이 발생한 걸까?
웹 접근성이란
A와 B씨가 서비스를 제대로 이용할 수 없었던 이유는 바로, ‘웹 접근성’ 이 제대로 지켜지지 않았기 때문이다.
‘웹 접근성(Web Accessibility)’ 은 장애를 가진 사람들이 비장애인과 동등한 웹 서비스를 사용할 수 있도록 설계 및 개발된 것이다. 또한 웹 접근성은 「국가정보화기본법」과 「장애인차별금지 및 권리구제 등에 관한 법률(이하 “장애인차별금지법”)」등 법률에 명시된 의무사항이다.
웹 접근성을 지켜야 하는 이유
웹은 하드웨어, 소프트웨어, 언어, 장소, 능력에 제약없이 모든 사람들이 사용할 수 있도록 설계되었다. 웹이 위와 같은 목표를 달성했을 때, 다양한 청력, 움직임, 시력, 인지 능력을 가진 사람들이 웹에 접근할 수 있게 된다.
이처럼 웹은 물리적 세상에서의 한계를 없애주는 역할을 한다. 웹에서는 시간과 물리적 한계가 존재하지 않는다. 또한, 장애인, 비장애인, 성별, 연령 간의 차별도 존재하지 않는다. 우리는 웹 세상에서 모두 동등해진다.
만약 웹 사이트, 애플리케이션, 기술, 도구가 공평하지 않고 불충분하게 설계된다면 그것은 보이지 않은 장벽을 만드는 것이다. 그렇기에 개발자는 제품 및 서비스에서 차별을 만들지 않기 위해 웹 접근성을 지켜야 한다.
웹 접근성의 종류
웹 접근성을 지키기 위해 할 수 있는 것들의 종류는 굉장히 많다. 이는 한국웹접근성인증평가원에서 발표한 ‘한국형 웹 컨텐츠 접근성 지침 2.1’에 자세히 설명되어있다.
한국형 웹 컨텐츠 접근성 지침 2.1은 W3C(World Wide Web Consortium)가 장애인 등이 웹 사이트에 접근하는 것을 보장하기 위해 만든 ‘웹 컨텐츠 접근성 지침 2.0(WCAG 2.0)’을 참고했다. 해당 지침은 WCAG 2.0의 12개 지침과 성공 기준의 중요도 A 항목을 중심으로 국내에 맞게 고려되어 개발되었다.
아래 표는 한국형 웹 컨텐츠 접근성 지침 2.1에서 말하는 웹 접근성 지침이다.
웹 접근성 지침
구분 | 항목 | 세부항목 | 관련 WCAG 2.0 기준 |
---|---|---|---|
1. 인식의 용이성 | 1.1. 대체 텍스트 제공 | 1.1.1 적절한 대체 텍스트 제공 | 1.1.1 Non-text Content |
1.2. 멀티미디어 대체 수단 제공 | 1.2.1 자막 제공 | 1.2.1 Audio-only and Video-only (Prerecorded), 1.2.2 Captions (Prerecorded), 1.2.3 Audio Description or Media Alternative | |
1.3. 명료성 | 1.3.1 색에 무관한 컨텐츠 인식 | 1.3.1 Info and Relationships, 1.4.1 Use of Color | |
1.3.2 명확한 지시 사항 제공 | 1.3.3 Sensory Characteristics | ||
1.3.3 텍스트 컨텐츠의 명도 대비 | 1.4.3 Contrast (중요도 AA 항목) | ||
1.3.4 자동 재생 금지 | 1.4.2 Audio Control | ||
1.3.5 컨텐츠 간의 구분 | 1.4.8 Visual Presentation (중요도 AAA 항목) | ||
2. 운용의 용이성 | 2.1. 입력장치 접근성 | 2.1.1 키보드 사용 보장 | 2.1.1 Keyboard |
2.1.2 초점 이동 | 2.1.2 No Keyboard Trap, 2.4.2 Focus Order | ||
2.1.3 조작 가능 추가 | - | ||
2.2. 충분한 시간 제공 | 2.2.1 응답시간 조절 | 2.2.1 Timing Adjustable | |
2.2.2 정지 기능 제공 | 2.2.2 Pause, Stop, Hide | ||
2.3 깜빡임 및 번쩍임 사용 제한 | 2.3.1 깜빡임과 번쩍임 사용 제한 | 2.3.1 Three Flashes or Below | |
2.4 쉬운 내비게이션 | 2.4.1 반복 영역 건너뛰기 | 2.4.1 Bypass Blocks | |
2.4.2 제목 제공 | 2.4.2 Page Titled | ||
2.4.3 적절한 링크 텍스트 | 2.4.4 Link Purpose | ||
3. 이해의 용이성 | 3.1 가독성 | 3.1.1 기본 언어 표시 | 3.1.1 Language of Page |
3.2 예측 가능성 | 3.2.1 사용자 요구에 따른 실행 | 3.2.1 On Focus, 3.2.2 On Input | |
3.3 컨텐츠의 논리성 | 3.3.1 컨텐츠의 선형 구조 | 1.3.2 Meaningful Sequence | |
3.3.2 표의 구성 | 1.3.1 Info and Relationships | ||
3.4 입력의 도움 | 3.4.1 레이블 제공 | 3.3.2 Labels or Instructions | |
3.4.2 오류 정정 | 3.3.1 Error Identification | ||
4. 견고성 | 4.1 문법 준수 | 4.1.1 마크업 오류 방지 | 4.1.1 Parsing |
4.2 웹 애플리케이션 접근성 | 4.2.1 웹 애플리케이션 접근성 준수 | 4.1.2 Name, Role, Value |
위 표에서의 웹 접근성은 크게 인식의 용이성, 운용의 용이성, 이해의 용이성, 견고성 4가지로 나눌 수 있다. 다만, 해당 글에서는 모두 다루기는 양이 방대하다. 그래서 스크린 리더와 밀접한 관계가 있는 항목만을 다루려고 한다.
스크린 리더
스크린 리더(Screen Reader) 는 디스플레이 화면에 표시된 내용과 사용자가 입력한 키보드 정보, 마우스 좌표 등을 비시각적인 방식으로 전달해주는 소프트웨어 애플리케이션이다. 이때, 비시각적인 방식으로는 텍스트 음성 변환, 점자 또는 사운드 아이콘 등이 있다. 따라서 스크린 리더는 시각 장애, 문맹, 학습 장애가 있는 사람들에게 필수적이다.
스크린 리더는 비시각적인 방식으로 정보를 전달하여, 시각 장애인이나 다른 접근성 요구가 있는 사용자들이 웹 콘텐츠를 원활하게 이용할 수 있도록 돕는다. 이러한 접근성을 더욱 향상시키기 위해 WAI-ARIA 가 도입되었다.
WAI-ARIA?
먼저 WAI-ARIA에 대해 살펴 보기 전에 RIA에 대해 알아보자.
웹의 빠른 발전으로 인해, 웹은 더이상 문서의 개념이 아닌 애플리케이션처럼 사용되면서 사용자 경험(User eXperience, UX)을 중시하게 되었다. 이런 요구를 해결하기 위해 등장한 것이 리치 인터넷 애플리케이션(Rich Internet Applications)이다. RIA는 정적인 HTML과 단순한 자바스크립트를 넘어 보다 동적인 자바스크립트와 Ajax(Asyncronous Javascript and XML) 등의 기술을 활용한다. 이로 인해 향상된 UX를 사용자에게 제공할 수 있다.
그러나, 모든 사용자가 동등하게 접근할 수 없다는 문제가 존재했다. 스크린 리더 등의 보조기술을 사용하는 사용자는 RIA 기술를 활용한 웹 애플리케이션을 제대로 사용할 수 없었다. 이로 인해 등장한 것이 바로 WAI-ARIA(Web Accessibility Initiative - Web Accessible Rich Internet Applications) 이다. WAI-ARIA는 W3C에서 웹 컨텐츠 및 웹 애플리케이션의 접근성과 상호 운용성을 개선하기 위해 발표한 기술 명세이다. 역할(Role), 속성(Property), 상태(State) 정보를 추가하여 스크린 리더 및 보조기기 등에서 접근성 및 상호 운용성을 향상시킨다.
WAI-ARIA의 3가지 기능
-
역할(Role)
유저 인터페이스(User Interface, UI)에 포함된 특정 컴포넌트의 역할을 정의한다.
페이지의 검색 영역인지, 네비게이션 요소인지, 제목 인지 등의 명확한 기능을 부여한다. -
속성(Property)
컴포넌트의 특징이나 상황을 정의한다.
폼의 입력 필드가 필수 항목인지, 팝업이 뜨는지, 업데이트 된 정보가 있는지 등의 상황을 사용자가 인지할 수 있도록 한다. 속성명으로aria-\*
라는 접두사를 사용한다. -
상태(State)
컴포넌트의 상태 정보를 정의한다.
메뉴가 펼쳐진 상태인지, 적절한 값이 입력되었는지, 컨텐츠가 숨김 상태인지 등을 나타낸다.
WAI-ARIA 작성 방법
다음은 어떻게 WAI-ARIA를 작성하면 좋을지 알아보자.
랜드마크
랜드마크(Landmark Role)는 웹 페이지의 특정 컨텐츠가 어떤 역할을 하는지 쉽게 식별할 수 있도록 도와주는 역할을 한다. 이는 웹 접근성을 높이기 위한 기능으로, 기존의 건너뛰기 링크(스크린 리더 사용자를 위해 페이지의 특정 부분으로 바로 이동할 수 있는 링크)보다 발전된 형태이다. 랜드마크는 HTML 요소에 role
속성을 사용하여 컨텐츠 역할을 지정하면 사용할 수 있다.
랜드마크를 사용하면 컨텐츠 블록의 제목을 제공하는 것보다 더 명확하게 영역을 구분할 수 있다. 예를 들어, 네비게이션 바, 주 컨텐츠 영역, 푸터 등을 쉽게 구분할 수 있다.
<!-- 컨텐츠 블록의 제목을 제공하는 형태 -->
<section>
<h2>소개</h2>
<p>해당 글에 대한 소개입니다.</p>
</section>
<!-- 랜드마크를 사용한 형태 -->
<main role="main">
<h1>주요 콘텐츠</h1>
<p>여기에 주요 콘텐츠가 들어갑니다.</p>
</main>
랜드마크 종류
랜드마크는 다음 표와 같이 8가지의 기능을 제공한다.
역할(Role) | 설명 | HTML5 요소 |
---|---|---|
application | 웹 애플리케이션 영역을 선언. 스크린 리더가 웹 브라우저 탐색 키를 애플리케이션에게 돌려줌. | N/A |
banner | 사이트의 로고나 제목 등을 포함하는 헤더 정보 영역. 사이트 아이덴티티 정보를 포함. | <header> |
navigation | 웹 사이트의 내비게이션 영역. 링크 모음을 포함. | <nav> |
main | 메인 콘텐츠 영역. 웹 페이지 내에서 한 번만 선언 가능. | <main> |
complementary | 메인 콘텐츠를 보충하는 부가적인 내용의 영역. 메인 콘텐츠에서 분리되어도 의미가 있음. | <aside> |
form | 사용자가 입력 가능한 폼 영역. 검색 폼은 제외. | <form> |
search | 검색을 위한 입력 폼 영역. | N/A |
contentinfo | 문서의 메타데이터 영역. 저작권 정보, 주소, 연락처, 개인정보 정책 등을 포함. | <footer> |
HTML5의 섹션 관련 요소와 WAI-ARIA를 같이 사용할 경우 해당 기능이 무효화 되거나 충돌이 발생할 수 있다. 따라서, 중복해서 사용하지 않도록 해야 한다.
HTML요소의 역할 변경 제한
ARIA를 이용하여 요소의 역할을 변경하는 것을 제한한다.
아래 코드를 예시로 들어보자.
<h1 role="“button”">버튼</h1>
위 코드는 h1
요소에 button 역할을 부여했다. h1
은 heading의 역할을 가지는데 ARIA를 사용하여 heading의 역할이 아닌 button의 역할을 하도록 강제했다. 이렇게 ARIA를 사용하여 본질적인 역할을 변경하는 것은 좋지 않다. h1
요소에 button 역할을 주고 싶다면 다음과 같이 사용한다.
<!-- h1 하위 요소로 button 사용 -->
<h1><button>버튼</button></h1>
<!-- h1 하위 요소로 span을 사용하여 role="button" 부여 -->
<h1><span role="button" tabindex="“0”">>버튼</span></h1>
위와 같은 방법으로 h1
의 본질적인 역할은 해치지 않으면서 button을 사용할 수 있게 되었다.
키보드 사용 보장
탭, 드래그 앤 드롭, 슬라이드, 스크롤 등과 같이 사용자와 상호작용이 필요한 대화형 UI의 경우 키보드로도 접근과 사용이 가능해야 한다. 키보드 포커스를 받지 못하는 요소의 경우 tabindex
속성을 사용하여 키보드 포커스를 받을 수 있도록 한다.
이때 tabindex
속성에 0을 지정하면 화면에 표시된 순서대로 키보드 포커스가 된다. 만약, 0보다 작은 값을 지정할 경우 키보드 포커스를 받을 수 없게 된다.
<!-- 키보드 포커스 X -->
<span role="“button”" tabindex="“-1”">버튼</span>
<!-- 키보드 포커스 O -->
<span role="“button”" tabindex="“0”">버튼</span>
그렇다면, tabindex
에 0보다 큰 양수의 값이 들어오면 어떻게 동작할까?
해당 요소는 지정한 순서대로 키보드 포커스를 받게 된다. 즉, tabindex
값이 낮을수록 먼저 포커스를 받게 된다. 이 방법을 통해 특정 요소들이 키보드 포커스를 받을 순서를 지정할 수 있다. 아래 0보다 큰 양수 값이 들어 왔을 경우에 대한 예시 코드를 살펴보자.
<!-- tabindex 순서를 지정 -->
<div tabindex="3">세 번째로 포커스</div>
<div tabindex="0">화면 표시 순서(네 번째)대로 포커스</div>
<div tabindex="1">첫 번째로 포커스</div>
<div tabindex="2">두 번째로 포커스</div>
<div tabindex="0">화면 표시 순서(다섯 번째)대로 포커스</div>
tabindex="1"
을 가진 요소가 가장 먼저 포커스를 받고, tabindex="2"
를 가진 요소가 그 다음, 그리고 tabindex="3"
을 가진 요소가 그 다음으로 포커스를 받는다. 이러한 방식은 화면에 표시된 순서와는 무관하게 포커스 순서를 지정할 수 있다.
다만, 이런 방식은 너무 많은 요소에 tabindex
를 설정하거나 높은 값을 사용하면 관리가 어려워질 수 있으므로 주의해서 사용해야 한다.
숨김 요소
스크린 리더 사용자를 위한 정보를 제공하지만, 단순히 화면에 보이지 않게만 하려는 경우에는 aria-hidden="true"
를 사용하면 안된다. aria-hidden="true"
로 지정된 요소는 스크린 리더에서 완전히 무시되기 때문에 스크린 리더는 이 요소가 아예 없다고 생각하게 된다.
<!-- 잘못된 aria-hidden 사용 예시: 중요한 버튼이 스크린 리더에서 무시됨 -->
<button aria-hidden="true">제출하기</button>
만약, aria-hidden=“true"
를 사용하여 숨김 요소에 대해 접근을 차단하고 싶다면, CSS를 활용한다. CSS의 display 속성에 none 값을 지정하여 스크린 리더에서 접근할 수 없도록 하고 aria-hidden="true"
를 명시한다.
<style>
button {
display: none;
}
</style>
<button aria-hidden="“true”">버튼</button>
중요한 정보를 전달하거나 버튼, 링크 같은 역할을 하는 요소에 role="presentation"
속성을 부여해서는 안 된다. 이 속성은 스크린 리더에게 해당 요소가 단순히 화면에 보이기 위한 것일 뿐이라고 인식하게 해서, 역할이 제대로 전달되지 않는다.
<!-- 잘못된 role="presentation" 사용 예시: 스크린 리더가 버튼 역할을 인식하지 못함 -->
<button role="presentation">다음 페이지로 이동</button>
레이블 제공
모든 대화형 UI 요소에는 반드시 레이블을 제공해야 한다. 레이블은 사용자가 해당 요소의 용도를 이해하는 데 도움을 준다. HTML의 <label>
요소를 사용하여 레이블을 제공하는 것이 가장 좋지만, aria-label
이나 aria-labelledby
와 같은 WAI-ARIA 속성을 사용해서도 레이블을 제공할 수 있다.
<!-- HTML <label> 요소를 사용한 예시 -->
<div class="container">
<label for="user-name">이름</label>
<input type="text" id="user-name" />
</div>
<!-- aria-label 속성을 사용한 예시 -->
<button aria-label="닫기" onclick="myDialog.close()">X</button>
<!-- aria-labelledby 속성을 사용한 예시 -->
<div>
<div id="name-label">이름</div>
<input type="text" aria-labelledby="name-label" />
</div>
그렇다면, HTML의 <label>
과 aria-label
, aria-labelledby
는 무슨 차이점이 있을까?
<label>
요소는 주로 입력 필드(input)와 함께 사용되며, 화면에 텍스트로 레이블이 표시되어 시각적으로 명확하게 한다.
aria-label
속성은 화면에 텍스트 레이블을 표시할 필요가 없는 경우에 유용하며, 보조 기술을 위해 텍스트 레이블을 제공한다.
aria-labelledby
속성은 다른 요소의 텍스트를 사용하여 레이블을 제공하며, 복잡한 레이블을 만들 때 유용하다.
Live Region
Live Region은 웹 문서나 위젯, 웹 애플리케이션의 일부가 동적으로 변경될 때, 사용자가 조작하지 않아도 변경된 내용과 진행 상태를 알릴 수 있도록 도와주는 속성이다. 이 속성은 모든 HTML 요소에 적용할 수 있다.
-
aria-live
aria-live
은 Live Region의 업데이트 내용을 사용자에게 알리는 방법을 설정한다. 기본값은 “off”이며, “polite”로 설정하면 사용자의 입력이 끝난 후 업데이트 내용을 알리고, “assertive”로 설정하면 즉시 알린다.<div aria-live="polite">사용자 입력 후 이 내용이 업데이트됩니다.</div>
-
aria-atomic
aria-atomic
은 Live Region의 내용이 업데이트될 때, 업데이트된 부분만 알릴 것인지 전체 내용을 알릴 것인지 설정한다. 기본값은 “false”이며, “true”로 설정하면 업데이트된 내용만 전달한다.<div aria-live="polite" aria-atomic="true">이 내용이 업데이트되면 전체를 알리지 않고 변경된 부분만 알립니다.</div>
-
aria-busy
aria-busy
은 Live Region이 업데이트 중인지 여부를 나타낸다. 기본값은 “false”이며, “true”로 설정하면 업데이트 중임을 알리고 이후 내용은 안내하지 않는다.<div aria-busy="true">업데이트 중입니다. 잠시만 기다려 주십시오.</div>
-
aria-relevant
aria-relevant
은 Live Region의 업데이트 시 어떤 종류의 변화에 대해 알릴지 설정한다. 기본값은 “additions text”이며, “additions”, “removals”, “text” 및 “all” 값으로 설정할 수 있다.<div aria-live="polite" aria-relevant="all">모든 변화가 이곳에 알림됩니다.</div>
마무리 말
웹 접근성은 단순히 법적 의무를 넘어, 모든 사람이 정보와 서비스를 동등하게 누릴 수 있도록 하는 기본적인 인권의 문제이다. 장애인뿐만 아니라 비장애인도 다양한 상황에서 웹 접근성의 혜택을 받을 수 있다. 웹의 창시자 팀 버너스리가 말한 것처럼, 웹의 힘은 보편성에 있다. 모든 사람이 장애에 상관없이 웹에 접근할 수 있는 환경을 만드는 것이야말로 우리 개발자가 추구해야 할 목표이다.
웹 접근성을 고려한 웹사이트는 더 많은 사용자에게 다가갈 수 있고, 이는 결국 더 나은 사용자 경험을 제공한다. 개발자는 이러한 접근성을 통해 정보의 격차를 줄이고, 모두가 평등하게 웹을 사용할 수 있는 환경을 만들어야 한다. 이를 통해 더 포용적이고 공정한 디지털 세상을 만들어 나가는 것이 우리의 책임이다.
Comments