적용 방법
랜드마크와 제목 구조
랜드마크와 제목 계층으로 페이지 구조를 만들고, 건너뛰기 링크와 페이지 제목으로 빠르게 이동하고 위치를 알 수 있게 하는 방법을 정리합니다.
왜 구조가 필요한가
눈으로 보는 사용자는 페이지를 훑어보고 머리글·메뉴·본문·사이드바를 한눈에 구분합니다. 화면낭독기 사용자는 같은 일을 랜드마크(landmark)와 제목(heading)으로 합니다. NVDA에서는 D 키로 다음 랜드마크로, H 키로 다음 제목으로, 1~6 키로 해당 수준의 제목으로 이동하고, 랜드마크·제목 목록 대화상자(NVDA+F7)로 페이지 전체 구조를 확인합니다. VoiceOver는 로터, TalkBack은 읽기 컨트롤로 같은 이동을 지원합니다.
구조가 없으면 사용자는 페이지 처음부터 모든 링크와 문단을 하나씩 들어야 원하는 곳에 도달합니다. 랜드마크·제목·건너뛰기 링크는 WCAG 1.3.1 정보와 관계, 2.4.1 블록 건너뛰기, 2.4.6 제목과 레이블과 직접 관련됩니다.
HTML 요소와 랜드마크 역할
랜드마크는 대부분 HTML 구획 요소로 자동 생성됩니다. role을 따로 붙이지 않고 HTML 요소를 쓰는 것이 원칙입니다(HTML과 ARIA 대응 참고).
| HTML | 랜드마크 역할 | 조건 |
|---|---|---|
<header> | banner | <article>, <aside>, <main>, <nav>, <section> 안에 있지 않을 때만. 그 안에 있으면 랜드마크가 아닙니다. |
<nav> | navigation | 항상 |
<main> | main | 항상. 페이지에 하나만 보이게 둡니다. |
<aside> | complementary | 최상위 수준일 때. <article>·<section> 등 안에 있으면 이름이 있을 때만 complementary가 됩니다(HTML-AAM). |
<footer> | contentinfo | <header>와 같은 조건 |
<section> | region | 접근 가능한 이름이 있을 때만. 이름이 없으면 일반 요소입니다. |
<form> | form | 접근 가능한 이름이 있을 때만 랜드마크로 노출됩니다. |
<search> | search | 항상. 비교적 최근 HTML에 추가된 요소이므로, 오래된 브라우저를 지원해야 하면 <form role="search">를 씁니다. |
<body>
<a class="skip-link" href="#content">본문 바로가기</a>
<header>
<a href="/">ARIA 가이드</a>
<nav aria-label="주 메뉴">...</nav>
<search>
<form action="/search">
<label for="q">사이트 검색</label>
<input type="search" id="q" name="q">
<button>검색</button>
</form>
</search>
</header>
<main id="content" tabindex="-1">
<h1>접근 가능한 이름 계산</h1>
...
</main>
<aside aria-labelledby="rel-h">
<h2 id="rel-h">관련 문서</h2>
...
</aside>
<footer>...</footer>
</body>모든 콘텐츠를 랜드마크 안에
APG는 페이지의 모든 콘텐츠가 어떤 랜드마크 안에 들어가도록 권합니다. 랜드마크 밖에 남은 콘텐츠는 랜드마크로 이동하는 사용자가 놓치기 쉽습니다. 자세한 구성은 랜드마크 패턴을 참고하세요.
같은 랜드마크가 여러 개일 때 이름 붙이기
주 메뉴와 하단 메뉴처럼 같은 역할의 랜드마크가 두 개 이상이면, 랜드마크 목록에 “탐색, 탐색”만 나열되어 구분할 수 없습니다. 이때는 aria-label 또는 aria-labelledby로 각각 이름을 줍니다.
<nav>...</nav>
<nav>...</nav>
<!-- 랜드마크 목록: "탐색", "탐색" --><nav aria-label="주 메뉴">...</nav>
<nav aria-label="이동 경로">...</nav>
<!-- 랜드마크 목록: "주 메뉴 탐색", "이동 경로 탐색" -->- 이름에 역할 이름을 넣지 않습니다.
aria-label="주 메뉴 내비게이션"은 “주 메뉴 내비게이션 탐색”처럼 중복되어 읽힙니다. - 화면에 제목이 있으면
aria-labelledby로 그 제목을 참조합니다. 보이는 텍스트와 이름이 일치하고 번역도 함께 바뀝니다. banner,main,contentinfo는 보통 페이지에 하나씩이므로 이름이 필요 없습니다.<section>에 이름을 주면 region 랜드마크가 됩니다. 중요한 구획에만 이름을 주고, 모든 section을 랜드마크로 만들지 않습니다. 랜드마크가 너무 많으면 오히려 탐색이 어렵습니다.
제목 계층 설계
제목은 문서의 목차입니다. <h1>~<h6>의 숫자는 글자 크기가 아니라 내용의 계층을 뜻합니다. 크기는 CSS로 조절하고, 수준은 내용 구조에 맞춥니다.
<h1>은 페이지의 주제를 나타냅니다. 보통<main>안에 하나 둡니다. 로고를 h1으로 감싸는 것보다 문서 제목을 h1으로 두는 것이 이동에 유리합니다.- 수준을 건너뛰지 않습니다. h2 다음에 바로 h4가 오면 중간 단계가 빠진 것처럼 들립니다. 명세 위반은 아니지만 구조 파악을 어렵게 합니다.
- 제목처럼 보이는 텍스트는 제목 요소로 만듭니다. 굵은
<div>는 화면에서는 제목이지만 보조기술에는 일반 문단입니다(1.3.1). - 제목이 아닌 것에 제목 요소를 쓰지 않습니다. 글자를 크게 하려고 h 요소를 쓰면 목차가 오염됩니다.
- 제목 텍스트는 내용을 설명해야 합니다(2.4.6). “안내”, “기타”보다 “배송 안내”, “환불 규정”이 낫습니다.
<div class="title-lg">주문 내역</div>
<h4>2026년 10월</h4>
<h2 class="small">배송 조회</h2><h1>주문 내역</h1>
<h2>2026년 10월</h2>
<h2 class="title-sm">배송 조회</h2>HTML 요소를 쓸 수 없는 경우(예: 서드파티 위젯 안)에만 role="heading"과 aria-level을 씁니다. heading 역할은 aria-level이 없으면 수준 2로 처리됩니다.
<div role="heading" aria-level="3">결제 수단</div>section 중첩과 제목 수준
과거 HTML 명세의 “문서 개요(outline) 알고리즘”은 <section> 안의 <h1>을 자동으로 낮은 수준으로 해석한다고 했지만, 이를 구현한 브라우저나 화면낭독기는 없었고 HTML 명세에서도 삭제되었습니다. 중첩 깊이와 상관없이 제목 수준을 직접 맞게 써야 합니다.
건너뛰기 링크
키보드 사용자는 페이지마다 반복되는 머리글과 메뉴를 매번 Tab으로 지나가야 합니다. 건너뛰기 링크(skip link)는 페이지의 첫 번째 포커스 가능한 요소로 두어 본문으로 바로 이동하게 합니다. 랜드마크와 제목도 2.4.1을 충족하는 방법이지만, 화면낭독기를 쓰지 않는 키보드 사용자에게는 건너뛰기 링크가 가장 확실한 수단입니다.
<a class="skip-link" href="#content">본문 바로가기</a>
...
<main id="content" tabindex="-1">...</main>.skip-link {
position: absolute;
left: 8px;
top: -100px; /* 평소에는 화면 밖 */
}
.skip-link:focus {
top: 8px; /* 포커스를 받으면 화면에 나타남 */
}
main:focus { outline: none; } /* 프로그램으로 옮긴 포커스의 테두리만 감춤 (선택) */- 포커스를 받으면 보여야 합니다.
display: none으로 숨기면 포커스를 받을 수 없어 쓸모가 없습니다. 숨기는 방법의 차이는 콘텐츠 숨기기를 참고하세요. - 도착 지점에
tabindex="-1"을 주면 일부 브라우저에서 포커스가 본문으로 확실히 옮겨지고, 다음Tab이 본문 안에서 이어집니다. - 링크 대상 ID가 실제로 존재하는지 확인합니다. SPA에서는 해시 링크가 라우터에 가로채이지 않게 주의합니다.
- 링크가 여러 개 필요하면(“주 메뉴 바로가기”, “검색 바로가기”) 묶어서 둘 수 있지만, 두세 개 이내로 유지합니다.
페이지 제목(title)
<title>은 브라우저 탭, 방문 기록, 북마크에 쓰이고 화면낭독기가 페이지를 열 때 가장 먼저 읽는 정보입니다. WCAG 2.4.2 페이지 제목(수준 A)은 각 페이지에 주제나 목적을 설명하는 제목을 요구합니다.
- 구체적인 내용을 앞에, 사이트 이름은 뒤에 둡니다. 탭이 많을 때 앞부분만 보여도 구분됩니다. 예:
<title>장바구니 (3개) - 쇼핑몰</title> - 모든 페이지가 같은 제목을 쓰지 않습니다. 검색 결과, 단계형 폼, 오류 상태를 제목에 반영하면 좋습니다(예: “오류 2건 - 회원가입 2/3단계”).
- SPA에서는 화면이 바뀔 때마다
document.title을 갱신해야 합니다. 동적 콘텐츠와 SPA에서 자세히 다룹니다. - 페이지 언어를
<html lang="ko">로 지정해야 제목과 본문이 올바른 음성으로 읽힙니다(3.1.1 페이지 언어).
구조 살펴보기 데모
아래 예시 페이지 코드를 분석해, 버튼을 누르면 화면낭독기의 랜드마크 목록·제목 목록과 비슷하게 구조를 뽑아 보여 줍니다. “구조 문제 넣기”를 누르면 흔한 실수가 적용된 결과를 비교할 수 있습니다.
예시 페이지 코드
실시간 코드
점검 방법
- 화면낭독기의 랜드마크 목록에서 머리글·주 메뉴·본문·바닥글이 모두 보이고, 같은 역할이 여러 개면 이름으로 구분되는지 확인합니다.
- 제목 목록만 읽어도 페이지 내용이 목차처럼 파악되는지, 수준이 건너뛰지 않는지 확인합니다.
- 페이지를 연 뒤 첫
Tab에 건너뛰기 링크가 보이는 상태로 나타나고, 누르면 본문으로 이동하는지 확인합니다. - 브라우저 탭의 제목이 페이지 내용과 맞는지 확인합니다.
- 브라우저 확장 도구(예: 랜드마크·제목 시각화 도구)나 개발자 도구의 접근성 트리로 구조를 한 번에 볼 수 있습니다. 도구 안내는 테스트 도구를 참고하세요.