제목·랜드마크·페이지 제목으로 문서 구조 잡기
눈으로 보는 사람은 글자 크기와 여백만 보고도 "여기가 제목, 저기가 메뉴, 이쪽이 본문"이라고 순식간에 파악합니다. 화면낭독기 사용자에게는 그 시각 정보가 없습니다. 대신 제목(heading), 영역(landmark), 페이지 제목(title)이라는 세 가지 구조 신호로 페이지를 훑습니다. 이 신호가 없거나 틀리면, 페이지는 위에서 아래로 끝없이 읽어 내려가야 하는 한 덩어리 텍스트가 됩니다.
1. 사용자는 페이지를 "읽는" 것이 아니라 "훑는다"
화면낭독기(NVDA, JAWS, VoiceOver 등)에는 문서를 처음부터 끝까지 듣는 것 말고도 요소 종류별로 건너뛰는 탐색 기능이 있습니다. 예를 들어 NVDA에서는 H 키로 다음 제목, D 키로 다음 영역(landmark), NVDA+F7로 제목·링크·영역 목록을 한 번에 봅니다. VoiceOver는 로터(VO+U)에서 같은 목록을 제공합니다. WebAIM이 정기적으로 실시하는 화면낭독기 사용자 설문에서도 긴 페이지에서 정보를 찾을 때 제목을 이용해 이동한다는 응답이 가장 큰 비중을 차지해 왔습니다.
이 말은 곧, 제목 목록만 뽑아 봐도 페이지의 목차가 되어야 한다는 뜻입니다. 다음 두 목차를 비교해 보세요.
| 제목 구조가 좋은 페이지 | 제목 구조가 나쁜 페이지 |
|---|---|
| h1 가을 시즌 아우터 h2 신상품 h2 베스트 10 h2 배송·교환 안내 h3 배송비 h3 교환·반품 |
(제목 없음 — 크게 꾸민 <div> 뿐)또는 h4 신상품 h1 베스트 10 h3 배송비 h2 (빈 제목) |
왼쪽은 제목만 들어도 페이지 구성을 이해할 수 있지만, 오른쪽은 어디가 상위이고 하위인지조차 알 수 없습니다.
2. 제목(heading)을 쓰는 규칙
2-1. 스타일이 아니라 의미로 고른다
"이 제목은 글자가 작았으면 좋겠으니 h5로"는 가장 흔한 실수입니다. 제목 레벨은 문서 안에서의 위계를 나타내는 것이고,
글자 크기는 CSS로 정합니다. 반대로 큰 글씨로 보이게 하려고 <div class="title">만 쓰면 제목이 존재하지 않는 페이지가 됩니다.
<!-- 나쁨: 시각만 제목 -->
<div class="big-title">배송·교환 안내</div>
<!-- 좋음: 의미는 h2, 모양은 CSS -->
<h2 class="section-title">배송·교환 안내</h2>
2-2. 레벨을 건너뛰지 않는다
h2 다음에 곧바로 h4가 오면, 화면낭독기 사용자는 "중간의 h3을 놓쳤나?" 하고 되돌아가 찾게 됩니다.
내려갈 때는 한 단계씩(h2 → h3), 올라갈 때는 몇 단계든 자유롭게(h4 → h2) 가능합니다.
이 도구의 heading-skip 규칙이 정확히 이 패턴을 찾습니다.
2-3. h1은 페이지당 하나, 페이지의 주제를 담는다
HTML 사양상 h1이 여러 개여도 문법 오류는 아니지만, 브라우저·보조기기가 "문서 개요 알고리즘"을 구현한 적이 없어
실제로는 위계가 평평해집니다. 실무에서는 페이지당 h1 하나를 두고, 그 내용이 <title>과 서로 어울리게 맞춥니다.
로고를 h1으로 감싸는 사이트가 많은데, 그러면 모든 페이지의 h1이 "사이트 이름"이 되어 페이지 구분이 사라집니다.
홈 화면이 아니라면 로고는 h1이 아닌 링크로 두세요.
2-4. 빈 제목, 장식용 제목을 만들지 않는다
CMS 편집기에서 빈 줄에 제목 서식이 걸려 <h2></h2>가 남는 경우, 제목 목록에 이름 없는 항목이 생깁니다(heading-empty).
간격을 벌리려고 제목 태그를 쓰는 것도 같은 문제입니다. 간격은 margin으로 해결합니다.
2-5. 카드·위젯 안의 제목 레벨
상품 카드 안에 넣을 제목이 h3인지 h4인지는 카드가 놓이는 자리의 위계에 따라 달라집니다. 같은 컴포넌트를 "추천 상품(h2)" 아래에 두면 h3, "추천 상품 → 카테고리(h3)" 아래 두면 h4가 되어야 합니다. 컴포넌트 라이브러리를 쓴다면 레벨을 속성으로 받게 만들어 두세요.
3. 랜드마크(영역)로 큰 덩어리를 표시한다
랜드마크는 "머리말, 메뉴, 본문, 보조 정보, 꼬리말" 같은 큰 구획을 이름 붙여 표시하는 방법입니다. 대부분은 별도의 ARIA 속성 없이 HTML 시맨틱 요소만으로 만들어집니다.
| HTML 요소 | 랜드마크 역할 | 메모 |
|---|---|---|
<header> | banner | <body> 바로 아래에 있을 때만. <article> 안의 header는 영역이 아님 |
<nav> | navigation | 여러 개면 aria-label로 구분 ("주요 메뉴", "페이지 하단 메뉴") |
<main> | main | 페이지당 하나. 반복되는 머리말·메뉴는 바깥에 둠 |
<aside> | complementary | 본문과 관련된 보조 내용(사이드바 등) |
<footer> | contentinfo | <body> 바로 아래에 있을 때만 |
<section>, <form> | region, form | 이름(aria-label 등)이 있을 때만 영역으로 노출됨 |
role="search" | search | 검색 폼을 감싸는 요소에 부여 |
<body>
<a href="#main" class="skip-link">본문 바로가기</a>
<header>… 로고, 검색 …</header>
<nav aria-label="주요 메뉴">…</nav>
<main id="main" tabindex="-1">
<h1>가을 시즌 아우터</h1>
…
</main>
<aside aria-label="최근 본 상품">…</aside>
<footer>… 사업자 정보 …</footer>
</body>
모든 콘텐츠는 어떤 랜드마크 안에 들어 있는 것이 좋습니다. 랜드마크 밖에 떠 있는 내용은 영역 단위로 이동할 때 건너뛰게 됩니다. 또한 랜드마크를 과하게 쓰면 목록이 길어져 오히려 쓸모가 줄어드니, 큰 덩어리 5~7개 정도로 유지하는 것이 보통입니다.
4. 본문 바로가기(스킵 링크)
키보드 사용자는 매 페이지마다 로고·검색·메뉴 수십 개를 Tab으로 지나야 본문에 닿습니다. 페이지 맨 앞에 "본문 바로가기" 링크를 두면 Tab 한 번, Enter 한 번으로 본문에 도착합니다(WCAG 2.4.1). 평소에는 화면 밖에 숨겨 두고 포커스를 받으면 나타나게 만드는 것이 일반적입니다.
.skip-link {
position: absolute; left: -9999px; top: 0;
background: #0f5f8f; color: #fff; padding: 10px 16px;
}
.skip-link:focus { left: 0; }
display:none이나 visibility:hidden으로 숨기면 포커스도 받지 못하므로 쓰면 안 됩니다.
링크가 가리키는 대상(id="main")이 실제로 존재하는지도 꼭 확인하세요. 대상이 없으면 눌러도 아무 일이 일어나지 않습니다.
이 도구는 링크 수가 많은 페이지에서 스킵 링크가 없으면 skip-link-missing으로 알려 줍니다.
5. 페이지 제목(<title>)과 언어(lang)
5-1. title은 탭·북마크·낭독기의 첫 마디
페이지를 열면 화면낭독기는 가장 먼저 <title>을 읽습니다. 브라우저 탭과 북마크, 검색 결과의 제목도 이 값입니다(WCAG 2.4.2).
"홈"이나 "Untitled"처럼 모든 페이지가 같은 제목이면 여러 탭을 열었을 때 구분할 수 없습니다.
- 페이지마다 고유하게 쓰고, 구체적인 정보를 앞에 둡니다:
장바구니 (3) - 예시 쇼핑몰 - 싱글 페이지 앱(SPA)은 라우트가 바뀔 때
document.title도 함께 갱신해야 합니다. - 화면에 보이는 h1과 서로 모순되지 않게 합니다.
5-2. lang 속성 — 발음이 달라진다
<html lang="ko">가 없으면 화면낭독기는 사용자 기기의 기본 언어로 읽습니다.
한국어 페이지를 영어 음성 엔진이 읽으면 알아들을 수 없는 소리가 됩니다(3.1.1).
페이지 중간에 다른 언어 문구가 섞여 있다면 그 부분에만 <span lang="en">처럼 표시해 줍니다(3.1.2).
이 도구에서는 html-lang-missing이 치명적으로 분류되는데, 한 줄 추가로 해결되면서 영향은 페이지 전체이기 때문입니다.
6. 직접 점검하는 방법
- 브라우저 개발자도구의 접근성 트리 — Chrome·Edge의 Elements 탭 → Accessibility 패널에서 각 요소의 역할과 이름을 볼 수 있습니다.
- 화면낭독기의 제목 목록 — NVDA NVDA+F7 → "제목" 탭. 목록만 보고 페이지가 이해되는지 확인합니다.
- CSS를 꺼 보기 — 스타일이 없어도 읽는 순서와 위계가 자연스러운지 봅니다. (개발자도구에서 스타일시트를 비활성화)
- 이 도구로 검사 —
heading-skip,heading-none,heading-empty,landmark-missing,skip-link-missing,title-missing,html-lang-missing7개 규칙이 구조 문제를 찾습니다.
7. 실무에서 자주 걸리는 패턴 요약
| 증상 | 원인 | 고치는 법 |
|---|---|---|
| 제목 목록이 비어 있음 | 제목을 div/span+CSS로만 표현 | 실제 h1~h6로 교체하고 스타일은 클래스로 |
| h1이 모든 페이지에서 사이트 이름 | 로고를 h1로 감쌈 | 로고는 링크로, h1은 페이지 주제로 |
| h2 다음 h4 | 글자 크기 맞추려고 레벨 선택 | 레벨은 위계대로, 크기는 CSS로 |
| 영역 목록에 "main"이 없음 | 본문이 그냥 div | <main>으로 교체(또는 role="main") |
| nav가 세 개인데 구분 불가 | 이름 없는 nav 반복 | 각각 aria-label 부여 |
| 모든 탭 제목이 같음 | SPA에서 title 미갱신 | 라우트 변경 시 document.title 갱신 |
자동 검사는 "제목이 있는가, 레벨이 건너뛰었는가"는 정확히 판정하지만, 제목의 문구가 내용을 잘 요약하는가는 판정하지 못합니다 (2.4.6 제목 및 레이블). 그 부분은 제목 목록만 소리 내어 읽어 보는 방식으로 사람이 확인하세요.
구조가 잡혀 있으면 다음 단계인 키보드 조작과 화면낭독기 테스트가 훨씬 수월해집니다. 어디부터 손댈지 모르겠다면 이 도구로 페이지를 검사해 구조 문제(분야 "구조·탐색")부터 확인해 보세요.