iBetter Books
수정

도입 스토리

"영어 원문 인용이 몇 군데 있는데, 스크린리더가 한국어 발음으로 읽어버려요." 김개발이 말했습니다.

NVDA가 "Web Content Accessibility Guidelines"을 한국어 억양으로 발음했습니다. 완전히 다른 소리였습니다.

"두 가지 문제예요." 박멘토가 설명했습니다. "첫째, 페이지 언어(lang="ko")는 맞게 설정되어 있지만, 인용된 영어 구절에 lang="en"이 없어요. 둘째, 언어만이 아니라 예측 가능성 문제도 있어요 — 어떤 페이지에서는 Select 선택 시 자동으로 페이지가 이동하거든요."

핵심 개념 설명

페이지 언어 — WCAG 3.1.1

<html> 태그에 lang 속성으로 페이지 기본 언어를 지정해야 합니다.

<!-- 한국어 페이지 --><!DOCTYPE html><html lang="ko"><head>...</head><body>...</body></html><!-- 영어 페이지 --><html lang="en"><!-- 언어 코드 예시 --><!-- ko: 한국어, en: 영어, ja: 일본어, zh: 중국어, fr: 프랑스어 -->

lang 속성이 없으면 스크린리더가 기본 언어(주로 영어)로 읽습니다. 한국어 콘텐츠를 영어 발음으로 읽으면 알아들을 수 없습니다.

부분 언어 — WCAG 3.1.2

페이지 중간에 다른 언어가 있으면 해당 요소에 lang을 지정합니다.

<p>  웹 접근성 국제 표준인  <span lang="en">Web Content Accessibility Guidelines</span>은  W3C가 발행합니다.</p><blockquote lang="en" cite="https://www.w3.org/TR/WCAG22/">  <p>"The power of the Web is in its universality."</p></blockquote><!-- 올바른 언어 코드 사용 --><p>이 서비스는 <span lang="ja">日本語</span>도 지원합니다.</p>

예측 가능성 — WCAG 3.2.1, 3.2.2

사용자가 예상하지 못한 동작이 발생하면 안 됩니다.

포커스 획득 시 자동 동작 금지 (WCAG 3.2.1):

<!-- 잘못된 예: 포커스만으로 팝업 열림 --><input  type="text"  onfocus="openCalendar()"><!-- 올바른 예: 사용자 의도적 행동(클릭/Enter)으로 열기 --><div class="date-field">  <input type="text" id="date" readonly>  <button    type="button"    aria-label="날짜 선택기 열기"    onclick="openCalendar()"  >    📅  </button></div>

입력 시 자동 제출 금지 (WCAG 3.2.2):

<!-- 잘못된 예: 선택 즉시 페이지 이동 --><select onchange="window.location.href=this.value">  <option value="/home">홈</option>  <option value="/about">소개</option></select><!-- 올바른 예: 이동 버튼 별도 제공 --><div>  <label for="page-nav">페이지 이동</label>  <select id="page-nav">    <option value="/home">홈</option>    <option value="/about">소개</option>  </select>  <button    type="button"    onclick="window.location.href=document.getElementById('page-nav').value"  >    이동  </button></div>

일관성 — WCAG 3.2.3, 3.2.4

  • WCAG 3.2.3: 여러 페이지에서 반복되는 내비게이션은 같은 순서여야 합니다.
  • WCAG 3.2.4: 같은 기능을 하는 컴포넌트는 일관된 이름을 써야 합니다.
<!-- 잘못된 예: 페이지마다 다른 메뉴 순서 --><!-- 홈 페이지: 홈 | 소개 | 제품 | 연락처 --><!-- 소개 페이지: 소개 | 홈 | 연락처 | 제품 --><!-- 잘못된 예: 같은 기능, 다른 이름 --><button>검색</button>  <!-- A 페이지 --><button>찾기</button>  <!-- B 페이지 --><button>Search</button> <!-- C 페이지 -->

같은 기능은 같은 레이블을 사용합니다. 스크린리더 사용자는 기억으로 사이트를 탐색하므로, 일관성이 매우 중요합니다.

단계별 실습

따라하기: 페이지 언어 확인하기

Chrome DevTools 콘솔에서 확인합니다.

// 페이지 언어 확인console.log('페이지 언어:', document.documentElement.lang);// lang 속성 없는 요소 찾기 (외국어 텍스트일 수 있는 요소)document.querySelectorAll('[lang]').forEach(el => {  console.log('언어 지정:', el.lang, el.textContent.substring(0, 30));});

변형하기: 자동 제출 폼 개선하기

Select 기반 내비게이션에 이동 버튼을 추가합니다.

// 기존 onchange 내비게이션을 접근성 있게 변환function makeSelectNavAccessible(selectEl) {  // onchange 핸들러 제거  selectEl.removeAttribute('onchange');  // 이동 버튼 생성  const btn = document.createElement('button');  btn.type = 'button';  btn.textContent = '이동';  btn.addEventListener('click', () => {    window.location.href = selectEl.value;  });  // Select 다음에 버튼 삽입  selectEl.parentNode.insertBefore(btn, selectEl.nextSibling);}

응용하기: 언어 일관성 감사

여러 페이지를 탐색하며 내비게이션 순서와 버튼 이름이 일관되는지 확인합니다.

정리와 확인

핵심 내용 요약

  • lang 속성(WCAG 3.1.1): <html lang="ko"> — 스크린리더 발음 정확도
  • 부분 언어(WCAG 3.1.2): 인용된 외국어에 <span lang="en"> 지정
  • 자동 동작 금지(WCAG 3.2.1/3.2.2): 포커스/입력으로 자동 페이지 이동 금지
  • 일관성(WCAG 3.2.3/3.2.4): 메뉴 순서와 컴포넌트 이름 일관성 유지

확인 문제

문제 1. <html lang="ko"> 없이 영어 스크린리더 사용자가 한국어 페이지를 방문하면?

스크린리더가 기본 언어(영어)로 한국어 텍스트를 발음하려 합니다.
완전히 알아들을 수 없는 발음이 됩니다.

문제 2. <select onchange="location.href=this.value">가 접근성 문제인 이유는?

키보드로 화살표 키를 눌러 옵션을 탐색하는 중에 onchange가 발생합니다.
원하는 옵션에 도달하기 전에 페이지가 이동해버려 키보드 사용자가 선택할 수 없습니다.

다음 챕터에서는 입력 도움과 오류 메시지를 다룹니다. 폼은 가장 많은 접근성 오류가 발생하는 곳입니다. 레이블, 힌트, 오류 메시지를 제대로 연결하는 방법을 알아봅니다.