Cert
UNIT · 1.1

시맨틱 HTML과 접근성

Semantic HTML and Accessibility

한국어 해설 KO

Original Text EN

의미론적 HTML 요소를 올바르게 사용하여 스크린리더와 보조기술이 페이지 구조를 정확히 해석할 수 있도록 하는 방법을 학습합니다.

Learn to use semantic HTML elements correctly so that screen readers and assistive technologies can accurately interpret page structure.

학습 목표

HTML5 랜드마크 요소와 그 역할을 설명할 수 있다

올바른 제목 계층 구조(h1~h6)를 적용할 수 있다

페이지 목적을 설명하는 `<title>`을 작성하고 SPA에서 갱신할 수 있다

인터랙티브 요소 선택의 올바른 기준을 설명할 수 있다

시맨틱 HTML이 보조기술에 미치는 영향을 이해한다

Learning Objectives

Explain HTML5 landmark elements and their roles

Apply correct heading hierarchy (h1–h6)

Write a `<title>` that describes the page's purpose and keep it updated in an SPA

Describe correct criteria for choosing interactive elements

Understand how semantic HTML impacts assistive technologies

시맨틱 HTML이 접근성의 기반인 이유

Why Semantic HTML Is the Foundation

시맨틱 HTML이란 태그의 시각적 표현이 아닌 의미와 역할에 맞는 HTML 요소를 사용하는 것입니다. 브라우저는 마크업에서 접근성 트리(Accessibility Tree)를 생성해 각 요소의 이름(name), 역할(role), 상태(state), 값(value)을 보조기술에 전달합니다 — 시맨틱 요소를 쓰면 이 정보가 공짜로 제공됩니다.

Semantic HTML means choosing elements by meaning and role, not visual appearance. The browser derives an Accessibility Tree from markup, exposing each element's name, role, state, and value to assistive technologies — semantic elements provide this information for free.

`<div>`로 만든 버튼과 `<button>`의 차이를 생각해보세요. `<button>`은 키보드 포커스, Enter/Space 활성화, '버튼' 역할 낭독, 폼 제출 동작을 기본 제공합니다. `<div onclick>`은 이 모든 것을 JavaScript와 ARIA로 재구현해야 하고, 하나라도 빠뜨리면 접근성 결함이 됩니다. '기본 요소를 쓸 수 있으면 쓴다'가 WAS 전체를 관통하는 원칙입니다.

Compare a `<div>` styled as a button with a real `<button>`: the `<button>` gives you keyboard focus, Enter/Space activation, a 'button' role announcement, and form submission behavior out of the box. A `<div onclick>` requires re-implementing all of that with JavaScript and ARIA — and every omission is an accessibility defect. 'Use the native element when you can' is the principle running through all of WAS.

랜드마크로 페이지 구조 만들기

Structuring Pages with Landmarks

HTML5 랜드마크 요소는 페이지의 주요 영역을 정의합니다: `<header>`(배너), `<nav>`(내비게이션), `<main>`(주요 콘텐츠, 페이지당 하나), `<article>`(독립 콘텐츠), `<section>`(주제별 그룹), `<aside>`(부가 정보), `<footer>`(콘텐츠 정보). 스크린리더 사용자는 랜드마크 단축키로 영역 간을 빠르게 이동합니다.

HTML5 landmark elements define the page's major regions: `<header>` (banner), `<nav>`, `<main>` (one per page), `<article>`, `<section>`, `<aside>`, and `<footer>` (contentinfo). Screen reader users jump between regions with landmark shortcuts.

실무 요령: 같은 유형의 랜드마크가 여러 개면 aria-label로 구분합니다(예: `<nav aria-label="주 메뉴">`와 `<nav aria-label="페이지 내 목차">`). 모든 콘텐츠는 어떤 랜드마크 안에든 속하는 것이 좋고, `<section>`은 접근 가능한 이름(aria-label/aria-labelledby)이 있을 때만 region 랜드마크로 노출됩니다.

Practical tips: when multiple landmarks of the same type exist, distinguish them with aria-label (e.g., `<nav aria-label="Main menu">` vs `<nav aria-label="Table of contents">`). Ideally all content lives inside some landmark, and note that `<section>` is exposed as a region landmark only when it has an accessible name (aria-label/aria-labelledby).

제목 계층 구조

Heading Hierarchy

`<h1>`은 페이지당 하나의 주요 제목으로 사용하고, `<h2>`~`<h6>`은 계층 순서대로 사용합니다. 레벨을 건너뛰면 안 됩니다(h1 → h3 금지). 제목은 시각적 크기가 아니라 콘텐츠의 논리적 구조를 나타내야 하며, 크기 조정은 CSS로 합니다.

Use `<h1>` as the single main heading per page, then `<h2>`–`<h6>` in order — never skip levels (no h1 → h3). Headings express the logical structure of content, not visual size; adjust size with CSS.

제목이 중요한 이유: 설문조사에서 스크린리더 사용자가 가장 많이 쓰는 페이지 탐색 방법이 제목 이동(H 키)입니다. 굵은 텍스트를 제목처럼 보이게 스타일링한 가짜 제목은 이 탐색에서 완전히 누락됩니다. 반대로 시각적 강조 목적으로 아무 데나 h 태그를 쓰면 구조가 왜곡됩니다.

Why headings matter: surveys consistently find heading navigation (the H key) is screen reader users' most-used way to explore pages. Fake headings — bold text styled to look like headings — are entirely invisible to that navigation. Conversely, using h tags anywhere just for visual emphasis distorts the structure.

페이지 제목(`<title>`)

Page Title (`<title>`)

`<title>`은 화면에 보이지 않지만 페이지를 대표하는 이름입니다. 스크린리더는 페이지가 로드되면 본문보다 먼저 title을 읽어주고, 사용자는 그 한 줄로 '내가 원한 페이지에 도착했는지'를 판단합니다. 탭을 여러 개 띄운 상태, 브라우저 방문 기록, 즐겨찾기, 검색 결과에서도 페이지를 구분하는 것은 이 문자열입니다. 제목이 없거나 모든 페이지가 같은 제목이면 이 판단 근거가 통째로 사라집니다.

`<title>` never appears in the page, yet it is the page's name. Screen readers announce it before any body content on load, and users decide from that one line whether they landed where they intended. It is also what distinguishes pages in a row of tabs, in browser history, in bookmarks, and in search results. With no title — or the same title everywhere — that basis for judgment disappears entirely.

좋은 제목은 '그 페이지에만 해당하는 정보'를 앞에, 사이트명을 뒤에 둡니다(예: `주문 내역 | 어울림몰`). 앞부분이 고유해야 하는 이유는 탭이 좁아지면 뒤쪽이 잘리고, 스크린리더 사용자도 앞부분을 먼저 듣기 때문입니다. 안티패턴은 명확합니다 — 모든 페이지가 `어울림몰`인 경우, `홈`처럼 맥락 없는 단어만 있는 경우, 사이트명·슬로건·키워드를 길게 나열해 정작 페이지 고유 정보가 뒤로 밀리는 경우.

A good title puts the page-specific information first and the site name last (e.g., `Order history | Eoullim Mall`). The front matters because narrow tabs truncate the end, and screen reader users hear the beginning first. The anti-patterns are clear: every page titled `Eoullim Mall`; context-free words like `Home`; or a pile of site name, tagline, and keywords that pushes the page's own identity out of sight.

SPA에서는 이 부분이 자주 깨집니다. 클라이언트 라우팅으로 화면만 바꾸면 문서는 그대로여서 document.title이 처음 로드한 페이지의 제목에 머무릅니다. 화면은 바뀌었는데 탭 이름과 스크린리더가 읽는 제목은 그대로인 상태가 되죠. 라우트가 바뀔 때마다 제목을 갱신해야 하며, Next.js App Router는 각 라우트의 `metadata`(또는 동적 라우트의 `generateMetadata`)로 이를 서버에서 처리합니다. 라우트 변경을 스크린리더에 알리는 것은 별개 문제로, 보통 제목 갱신과 함께 live region 안내를 같이 씁니다.

Single-page apps break this routinely. Client-side routing swaps the view without a new document, so document.title stays on whatever the first-loaded page set. The screen changed, but the tab label and the announced title did not. The title must be updated on every route change; in the Next.js App Router, each route's `metadata` export (or `generateMetadata` for dynamic routes) handles this on the server. Announcing the route change to screen readers is a separate concern, usually solved by pairing the title update with a live region message.

근거 기준: WCAG 2.4.2 페이지 제목(Level A) — '웹 페이지에는 주제나 목적을 설명하는 제목이 있어야 한다'. KWCAG 2.2에서는 6.4.2 제목 제공에 해당하며, 이 항목은 페이지 title뿐 아니라 프레임 제목(`<iframe title>`)과 콘텐츠 블록 제목까지 함께 요구합니다. 자동 검사 도구는 title 존재 여부와 중복 정도만 잡아낼 수 있고, 제목이 실제로 페이지 내용을 설명하는지는 사람이 판단해야 합니다.

The requirement: WCAG 2.4.2 Page Titled (Level A) — web pages have titles that describe topic or purpose. In KWCAG 2.2 this maps to 6.4.2 Titles Provided, which additionally covers frame titles (`<iframe title>`) and content-block headings. Automated tools can only detect whether a title exists and whether titles are duplicated; whether a title actually describes the page is a human judgment.

페이지 고유 정보를 앞에 두는 제목 — 잘못된 예와 올바른 예
<!-- ❌ 모든 페이지가 같은 제목: 탭 목록에서도, 스크린 리더로도 구분 불가 -->
<title>어울림몰</title>

<!-- ❌ 사이트명·슬로건이 앞을 차지해 페이지 고유 정보가 잘림 -->
<title>어울림몰 - 모두를 위한 쇼핑 - 주문 내역</title>

<!-- ✅ 페이지 고유 정보 + 구분자 + 사이트명 -->
<title>주문 내역 | 어울림몰</title>
Next.js App Router — 라우트마다 제목을 서버에서 지정
// app/layout.tsx — 사이트명은 템플릿으로 한 번만
export const metadata = {
  title: { template: "%s | 어울림몰", default: "어울림몰" },
};

// app/orders/page.tsx — 정적 라우트
export const metadata = { title: "주문 내역" };

// app/orders/[id]/page.tsx — 동적 라우트
export async function generateMetadata({ params }) {
  const { id } = await params;
  return { title: `주문 ${id}` };
}

인터랙티브 요소와 리스트

Interactive Elements and Lists

인터랙티브 요소 선택 기준: 동작 실행은 `<button>`, 페이지·위치 이동은 `<a href>`, 데이터 입력은 `<input>`, 선택 목록은 `<select>`. 링크와 버튼의 구분은 시험 단골입니다 — '어디로 가는가'는 링크, '무엇을 하는가'는 버튼입니다. href 없는 `<a>`는 키보드 포커스를 받지 못한다는 점도 주의하세요.

Choosing interactive elements: `<button>` for actions, `<a href>` for navigation, `<input>` for data entry, `<select>` for selection lists. The link-versus-button distinction is a favorite exam topic — 'where does it go' is a link; 'what does it do' is a button. Also note that an `<a>` without href cannot receive keyboard focus.

리스트 요소: 순서 없는 목록 `<ul>`, 순서 있는 목록 `<ol>`, 용어-설명 쌍은 `<dl>`. 스크린리더는 '목록, 3개 항목'처럼 항목 수와 현재 위치를 알려주므로, 시각적으로만 목록처럼 배치한 `<div>` 나열과 실제 목록 마크업은 사용 경험이 완전히 다릅니다.

Lists: `<ul>` for unordered, `<ol>` for ordered, `<dl>` for term–description pairs. Screen readers announce 'list, 3 items' and your position within it — so a stack of `<div>`s that merely looks like a list is a completely different experience from real list markup.

단원 퀴즈

9문제 · 오답은 오답노트에 자동 저장됩니다

1

페이지 이동(링크)에 가장 적합한 HTML 요소는?

2

다음 중 잘못된 제목 계층 구조는?

3

스크린리더 사용자가 페이지 주요 영역을 빠르게 탐색할 수 있게 해주는 HTML5 요소들은?

4

브라우저가 마크업에서 생성해 보조기술에 전달하는 구조는?

5

같은 유형의 랜드마크(nav)가 페이지에 여러 개 있을 때 올바른 처리는?

6

굵은 텍스트를 제목처럼 스타일링한 '가짜 제목'의 문제는?

7

쇼핑몰 주문 내역 페이지의 `<title>`로 가장 적절한 것은?

8

클라이언트 라우팅으로 화면을 전환하는 SPA에서 WCAG 2.4.2(페이지 제목)를 충족하려면 반드시 해야 하는 것은?

9

코드 리뷰에서 `<div onclick="submit()">제출</div>`을 발견했습니다. 가장 올바른 수정은?

로드맵으로
로그인하면 학습 메모를 작성할 수 있습니다.

댓글

댓글을 불러오는 중...

댓글을 작성하려면 로그인이 필요합니다.