웹 접근성 기초부터 다지기 1

kimgho
웹 접근성
웹 접근성 기초부터 다지기 1

개발을 하다 보면 <div>만으로 모든 레이아웃을 짜고 싶은 유혹에 빠집니다.
하지만 우리가 작성한 코드는 단순히 화면에 그려지는 그림이 아닙니다.
브라우저와 스크린 리더는 코드를 어떻게 해석할까요?
웹 접근성 첫 번째 글에서는 시맨틱 태그의 중요성과 요소에 대해 알아보겠습니다.

1. 브라우저가 코드를 읽는 법 (SEO)

브라우저는 HTML을 해석해서 DOM 트리를 만듭니다. 이때 시맨틱 태그는 각 부분이 어떤 역할을 하는지 명확한 명찰을 달아주는 역할을 합니다.

  • <div> (Non-semantic): 내용을 담는 투명한 비닐봉지입니다. 안에 금덩이가 들었는지 쓰레기가 들었는지 브라우저는 알 수 없습니다.
  • 시맨틱 태그 (<header>, <main> 등): "여기는 제목이야", "여기는 핵심 콘텐츠야"라고 알려줍니다.

2. 스크린 리더가 코드를 읽는 법 (접근성 트리)

스크린 리더는 DOM 트리를 직접 읽지 않습니다. 브라우저가 DOM을 바탕으로 만든 접근성 트리(Accessibility Tree)를 읽습니다. 이 트리는 4가지 핵심 요소로 구성됩니다.

  1. Role (역할): 이 요소가 무엇인가? (버튼, 링크, 체크박스 등)
  2. Name (이름): 레이블이 무엇인가? (제출, 메뉴)
  3. State (상태): 현재 어떤 상태인가? (체크됨, 펼쳐짐)
  4. Value (값): 내용은 무엇인가?

<div> vs <button> 비교

개발자가 <div>를 CSS로 버튼처럼 꾸몄을 때, 접근성 트리는 어떻게 반응할까요?

  • <div class="btn">로그인</div>:
    • 접근성 트리: "텍스트 그룹"으로 인식.
    • 문제점: 클릭 가능한지 알 수 없고, 탭(Tab) 키로 포커스도 잡히지 않습니다. (Role 정보 누락)
  • <button>로그인</button>:
    • 접근성 트리: Role: button 등록.
    • 이점: "로그인, 버튼"이라고 읽어주며, 자동으로 키보드 포커스와 엔터/스페이스바 작동이 지원됩니다.

3. 요소에 이름 붙이기 (Labeling)

스크린 리더에게 요소의 이름을 알려주는 방법은 우선순위가 있습니다.

우선순위 계산법

  1. aria-labelledby: 다른 요소의 ID를 참조 (가장 강력함)
  2. aria-label: 직접 문자열 입력 (화면 텍스트 무시)
  3. <label> 또는 내부 텍스트: 기본적인 HTML 방식

상황별 사용법

1) aria-label (직접 이름 붙이기)

화면에 텍스트 없이 아이콘만 있는 버튼에 사용합니다.

<button aria-label="창 닫기">
  <svg>...</svg>
</button>

2) aria-labelledby (다른 요소 참조)

이미 화면에 있는 텍스트를 레이블로 빌려 씁니다. 모달 제목 등을 연결할 때 유용합니다.

<h2 id="modal-title">회원 탈퇴</h2>
<div role="dialog" aria-labelledby="modal-title">...</div>

4. 보이지 않는 것을 다루는 기술

접근성에서 가장 중요한 것 중 하나는 누구에게 숨길 것인가를 결정하는 것입니다. 보이지 않는 요소를 처리하는 3가지 방법(display none, aria-hidden, visually-hidden) 비교 테이블

5. 동적인 상호작용 (Interaction)

키보드 제어권 (tabindex)

마우스를 못 쓰는 사용자는 Tab 키로 여행을 떠납니다.

  • tabindex="0": 원래 포커스를 못 받는 요소(div, span)를 탭 순서에 포함시킵니다.
  • tabindex="-1": 탭으로는 접근 못 하지만, 자바스크립트 element.focus()로는 이동 가능하게 합니다. (모달 열릴 때 포커스 이동 등)

상태 알려주기 (aria-expanded)

눈으로 보면 드롭다운 메뉴가 열린 것을 알지만, 스크린 리더는 모릅니다. 변화가 일어나는 요소(버튼)에 상태를 명시해야 합니다.

<button aria-expanded="false" aria-controls="menu-list">메뉴</button>

스크린 리더는 속성값이 false에서 true로 바뀌는 순간 "확장됨"이라고 사용자에게 즉시 알려줍니다.

6. 결론: ARIA의 제1원칙

접근성을 공부하다 보면 ARIA 속성을 남발하고 싶어집니다. 하지만 가장 중요한 원칙은 이것입니다.

"HTML 태그만으로 기능을 구현할 수 있다면, ARIA를 쓰지 마라."

ARIA는 HTML의 부족한 부분을 메우는 보조제일 뿐입니다. 시맨틱 태그를 올바르게 사용하는 것이 웹 접근성의 시작이자 끝입니다.