"같은 픽셀, 다른 기계. 브라우저는 HTML 을 읽는 여러 주체 중 하나일 뿐이야."
같은 픽셀의 두 페이지, 다른 의미
여기 코드 두 덩어리. 둘 다 브라우저에 띄우면 똑같이 렌더돼 — 헤더, 네비 스트립, 메인 기사, 사이드바, 푸터. 눈으로 보는 사용자한테는 같은 페이지야.
나머지 모두한테는 — screen reader, 검색 엔진, 접근성 감사, 미래의 동료 — 전혀 다른 페이지야.
Mental 전환
대부분의 입문자가 HTML 을 "CSS 로 스타일링하는 컨테이너 목록" 으로 배워. 그 모델은 3 주 정도 굴러가다가 다 망가져 — screen reader 가 의미 있는 걸 못 읽어내고, 검색 엔진이 쓰레기를 뽑고, 접근성 감사 도구가 경고 200 개를 토하고, React 리팩토링이 악몽으로 변해 (모든 component 가 <div> 바다라서).
올바른 mental model 은: HTML element 는 의미를 가진 명사야. <article> 은 "이건 자기 완결적인 콘텐츠 조각" 이라는 뜻. <nav> 는 "이건 네비게이션" 이라는 뜻. <button> 은 "클릭 가능하고 tab 키로 접근 가능하고 screen reader 가 버튼으로 announce 할 것" 이라는 뜻. CSS 는 의상이고; element 는 역할이야.
브라우저 말고 HTML 을 읽는 주체들
- Screen reader (VoiceOver, NVDA, JAWS, TalkBack) — landmark role, heading 구조, ARIA label 로 네비게이션해. Semantic element 가 공짜로 landmark 를 줘.
- 검색 엔진 — Google, Bing, DuckDuckGo 가
<article>,<h1>,<time>, microdata 에서 구조를 뽑아. 구조 좋으면 → 인덱싱 좋아져. - 브라우저 reader mode — Safari/Firefox 의 reader view 가 문자 그대로 semantic HTML 을 파싱해서 부가 요소를 벗겨내. 잘못된 markup = reader mode 작동 안 함.
- RSS reader, share preview 카드, 자동화 script — 다 DOM 을 걸으면서 의미를 찾아.
- 접근성 법 — WCAG, ADA, EAA. 응, 법이야. 접근성 부족으로 소송 진짜 걸려.
- 미래의 너 — 6 개월 후 이 코드 디버깅할 사람. Semantic markup 은 이야기처럼 읽히고;
<div>수프는 hex dump 처럼 읽혀.
매일 쓰는 Semantic 어휘
HTML5 에는 semantic element 가 수십 개 있지만, 작은 set 으로 페이지 80% 가 커버돼:
- Landmark:
<header>,<nav>,<main>,<aside>,<footer> - 콘텐츠 단위:
<article>,<section>,<figure>/<figcaption> - Heading:
<h1>–<h6>(문서 순서대로, 건너뛰지 않게) - 인터랙티브:
<button>,<a>,<label>,<input>,<details>/<summary> - 텍스트 레벨:
<em>,<strong>,<mark>,<time>,<code>,<abbr>
Landmark 는 외워. 콘텐츠 단위는 맞는 자리에 꺼내. 인라인 의미에는 <span class="bold"> 대신 텍스트 레벨 element 를 써.
만트라
<div> 로 빠져. <nav> 나 <article> 이 될 수 있었던 자리에 쓴 모든 <div> 는 접근성, SEO, 미래의 너한테 부과되는 작은 세금이야.피파의 노트
<button> 또는 <a>. 예뻐서가 아니라, 아빠가 가끔 VoiceOver 로 테스트하는데 별 의식 없이도 그냥 굴러가야 해서. Markup 자체가 접근성 레이어야.