도입 스토리
퇴근 후 박멘토가 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>를 두 개 사용하면 어떤 문제가 생기는가?
스크린리더 랜드마크 목록에 "내비게이션, 내비게이션"으로 표시되어
사용자가 어느 내비게이션인지 구분할 수 없습니다.
다음 챕터에서는 포커스 관리와 건너뛰기 링크를 다룹니다. 스킵 내비게이션이 왜 첫 번째 요소여야 하는지 알아봅니다.