iBetter Books
수정

도입 스토리

퇴근 후 박멘토가 NVDA를 켜고 자사 웹사이트를 열었습니다.

"NVDA+F7로 랜드마크 목록을 열어볼게요."

목록에는 아무것도 없었습니다. 랜드마크가 하나도 없었습니다.

"스크린리더 사용자는 Tab으로 링크를 하나씩 탐색하거나, 랜드마크로 이동하는 두 가지 방법을 씁니다. 랜드마크가 없으면 첫 번째 링크부터 순서대로 Tab을 눌러야 해요. 우리 사이트 상단 메뉴에 링크가 몇 개 있죠?"

"한 30개요?"

"그러면 본문에 도달하려면 Tab을 30번 눌러야 해요."

핵심 개념 설명

HTML 랜드마크 요소

HTML5 시맨틱 요소는 랜드마크(Landmark) 역할을 합니다. 스크린리더 사용자는 랜드마크 사이를 단축키로 빠르게 이동할 수 있습니다.

HTML 요소 ARIA 역할 용도
<header> banner 페이지 헤더 (로고, 메인 내비게이션)
<nav> navigation 내비게이션 링크 모음
<main> main 페이지 주요 콘텐츠
<footer> contentinfo 페이지 푸터 (저작권, 연락처)
<aside> complementary 보조 콘텐츠 (사이드바)
<section> region 독립적인 섹션 (레이블 필요)
<form> form 폼 영역 (레이블 필요)
<search> search 검색 영역
<!-- 올바른 랜드마크 구조 --><header>  <a href="/" aria-label="홈으로 이동">    <img src="logo.svg" alt="회사 로고">  </a>  <nav aria-label="주요 메뉴">    <ul>      <li><a href="/about">소개</a></li>      <li><a href="/products">제품</a></li>      <li><a href="/contact">연락처</a></li>    </ul>  </nav></header><main>  <h1>서비스 소개</h1>  <!-- 주요 콘텐츠 --></main><footer>  <p>© 2026 회사명. 모든 권리 보유.</p></footer>

여러 개의 같은 랜드마크 구별하기

<nav>가 두 개 이상이면 aria-label로 구별합니다.

<nav aria-label="주요 메뉴">  <!-- 상단 내비게이션 --></nav><nav aria-label="페이지 내 목차">  <!-- 사이드 내비게이션 --></nav><nav aria-label="하단 메뉴">  <!-- 푸터 내비게이션 --></nav>

스크린리더가 랜드마크 목록을 보여줄 때 "주요 메뉴 내비게이션", "페이지 내 목차 내비게이션"으로 표시됩니다.

페이지 제목 — WCAG 2.4.2

각 페이지는 고유하고 설명적인 제목이 있어야 합니다.

<!-- 잘못된 예: 모든 페이지 동일 --><title>회사 홈페이지</title><!-- 올바른 예: 페이지 내용을 먼저 --><title>로그인 | 회사 홈페이지</title><title>장바구니 (3개) | 쇼핑몰</title><title>404 페이지를 찾을 수 없음 | 회사 홈페이지</title>

페이지에 특정한 정보(장바구니 개수, 검색어, 에러 코드)를 제목에 포함하면 스크린리더 사용자가 페이지 탐색 목록에서 현재 위치를 빠르게 파악할 수 있습니다.

링크 목적 — WCAG 2.4.4

링크 텍스트만으로 목적지를 알 수 있어야 합니다.

<!-- 잘못된 예: 모호한 링크 텍스트 --><a href="/products/laptop-pro">더 보기</a><a href="/products/keyboard">더 보기</a><a href="/blog/post-1">여기를 클릭</a><!-- 올바른 예: 목적지를 설명하는 텍스트 --><a href="/products/laptop-pro">Laptop Pro 더 보기</a><a href="/products/keyboard">키보드 더 보기</a><!-- 또는 시각적으로는 "더 보기"이되, 스크린리더에는 전체 텍스트 --><a href="/products/laptop-pro">  <span aria-hidden="true">더 보기</span>  <span class="sr-only">Laptop Pro 상세 페이지</span></a>

스크린리더는 링크 목록을 뽑아서 탐색하는 기능이 있습니다. "더 보기, 더 보기, 더 보기..." 목록은 쓸모가 없습니다.

현재 위치 표시 — aria-current

내비게이션에서 현재 페이지를 명확히 표시합니다.

<nav aria-label="주요 메뉴">  <ul>    <li><a href="/">홈</a></li>    <li><a href="/about" aria-current="page">소개</a></li>    <li><a href="/products">제품</a></li>  </ul></nav>

aria-current="page"는 스크린리더가 "소개, 현재 페이지"라고 읽어줍니다.

단계별 실습

따라하기: 랜드마크 구조 확인하기

NVDA 사용 시 NVDA+F7, VoiceOver 사용 시 VO+U로 랜드마크 목록을 열어봅니다.

Chrome 확장 프로그램 Landmark Navigation (무료)을 사용하면 시각적으로 랜드마크 영역을 표시할 수 있습니다.

변형하기: 링크 텍스트 감사하기

페이지의 모호한 링크를 찾습니다.

// "더 보기", "click here", "자세히" 같은 모호한 링크 찾기const vagueLinks = ['더 보기', '여기', '클릭', 'click here', '자세히', '링크'];document.querySelectorAll('a').forEach(a => {  const text = a.textContent.trim().toLowerCase();  if (vagueLinks.some(v => text === v || text.includes(v))) {    console.warn('모호한 링크:', a.href, `"${a.textContent.trim()}"`);  }});

응용하기: 시맨틱 구조 개선

<div> 기반 레이아웃을 시맨틱 HTML로 리팩터링합니다.

<!-- 수정 전: div 남용 --><div class="header">  <div class="nav">...</div></div><div class="content">...</div><div class="footer">...</div><!-- 수정 후: 시맨틱 요소 --><header>  <nav aria-label="주요 메뉴">...</nav></header><main>...</main><footer>...</footer>

정리와 확인

핵심 내용 요약

  • 랜드마크: <header>, <nav>, <main>, <footer> — 스크린리더 빠른 탐색 지원
  • 여러 <nav> 구별: aria-label로 이름 부여
  • 페이지 제목(WCAG 2.4.2): 고유하고 설명적인 <title>
  • 링크 텍스트(WCAG 2.4.4): "더 보기" 금지 — 목적지를 설명
  • aria-current="page": 현재 페이지 내비게이션 항목 표시

확인 문제

문제 1. <main> 요소는 페이지에 몇 개여야 하는가?

하나만 있어야 합니다. 두 개 이상이면 스크린리더가 어느 것이 주요 콘텐츠인지 알 수 없습니다.

문제 2. <nav aria-label="..."> 없이 <nav>를 두 개 사용하면 어떤 문제가 생기는가?

스크린리더 랜드마크 목록에 "내비게이션, 내비게이션"으로 표시되어
사용자가 어느 내비게이션인지 구분할 수 없습니다.

다음 챕터에서는 포커스 관리와 건너뛰기 링크를 다룹니다. 스킵 내비게이션이 왜 첫 번째 요소여야 하는지 알아봅니다.