<!-- div 수프 시대의 전형적인 구조 -->
<div class="header">
<div class="logo">...</div>
<div class="nav">
<div class="nav-item">홈</div>
<div class="nav-item">소개</div>
</div>
</div>
<div class="content">
<div class="main">...</div>
<div class="sidebar">...</div>
</div>
<div class="footer">...</div>태그 | 역할 |
<header> | 소개 콘텐츠나 탐색 링크의 컨테이너. 페이지 전체 헤더나 섹션 헤더로 쓰인다 |
<nav> | 탐색 링크 묶음. 주요 메뉴, 사이드 링크 목록 등 |
<main> | 페이지의 주요 콘텐츠 영역. 페이지당 하나만 존재해야 한다 |
<article> | 독립적으로 배포하거나 재사용할 수 있는 콘텐츠 단위. 블로그 포스트, 뉴스 기사, 댓글 등 |
<section> | 주제별로 묶인 콘텐츠 구역. 제목(<h2>~<h6>)이 있어야 의미가 명확해진다 |
<aside> | 주요 콘텐츠와 간접적으로 연관된 부수적인 콘텐츠. 사이드바, 광고, 관련 링크 등 |
<footer> | 저작권, 연락처, 관련 링크 등 마무리 정보 |
태그 | 역할 |
<h1>~<h6> | 제목 계층. 문서 구조의 뼈대 역할 |
<p> | 문단 |
<figure> | 이미지, 다이어그램, 코드 등 독립적인 콘텐츠 묶음 |
<figcaption> | <figure> 내 캡션 |
<time> | 날짜나 시간. datetime 속성으로 기계가 읽을 수 있는 형식 지정 |
<address> | 가장 가까운 <article> 또는 <body>의 연락처 정보 |
<details> | 열고 닫을 수 있는 콘텐츠 컨테이너 |
<summary> | <details>의 요약 제목 |
<mark> | 현재 문맥에서 관련성이 있어 강조된 텍스트 |
<abbr> | 약어나 두문자어. title 속성으로 전체 단어 설명 |
태그 | 역할 |
<button> | 클릭 가능한 버튼 |
<a> | 하이퍼링크. href가 있으면 링크, 없으면 플레이스홀더 |
<form> | 사용자 입력 폼 |
<input> | 입력 필드. type 속성으로 역할이 결정된다 |
<label> | 폼 요소의 레이블 |
<fieldset> | 관련 폼 컨트롤 묶음 |
<legend> | <fieldset>의 제목 |
<!-- before: 클래스 이름을 모르면 구조를 파악하기 어렵다 -->
<div class="wrap">
<div class="hd">
<div class="gnb">...</div>
</div>
<div class="ct">
<div class="lnb">...</div>
<div class="main-ct">...</div>
</div>
</div>
<!-- after: 태그만 봐도 구조가 보인다 -->
<body>
<header>
<nav>...</nav>
</header>
<main>
<aside>...</aside>
<article>...</article>
</main>
</body>

<!-- 이 두 코드는 스크린리더 입장에서 같다 -->
<nav>...</nav>
<div role="navigation">...</div>
<!-- 이 두 코드도 같다 -->
<button>클릭</button>
<div role="button" tabindex="0">클릭</div>태그 | 암묵적 ARIA role | 조건 |
<header> | banner | <article>, <aside>, <main>, <nav>, <section> 외부에 있을 때 |
<header> | generic | <article>, <section> 등 sectioning 요소 안에 있을 때 |
<footer> | contentinfo | sectioning 요소 외부에 있을 때 |
<footer> | generic | sectioning 요소 안에 있을 때 |
<nav> | navigation | 항상 |
<main> | main | 항상 |
<article> | article | 항상 |
<section> | region | 접근 가능한 이름(accessible name)이 있을 때 |
<section> | generic | 접근 가능한 이름이 없을 때 |
<aside> | complementary | 항상 |
<h1>~<h6> | heading | 항상 |
<ul>, <ol> | list | 항상 |
<li> | listitem | 항상 |
<button> | button | 항상 |
<a href="..."> | link | href 속성이 있을 때 |
<a> | generic | href 속성이 없을 때 |
<form> | form | 접근 가능한 이름이 있을 때 |
<form> | generic | 접근 가능한 이름이 없을 때 |
<input type="text"> | textbox | 항상 |
<input type="checkbox"> | checkbox | 항상 |
<input type="radio"> | radio | 항상 |
<select> | listbox | 항상 |
<table> | table | 항상 |
<figure> | figure | 항상 |
<details> | group | 항상 |
<dialog> | dialog | 항상 |
<img alt="..."> | img | alt가 빈 문자열이 아닐 때 |
<img alt=""> | presentation | alt가 빈 문자열일 때 |
<!-- region이 되는 section — 스크린리더 랜드마크에 등록됨 -->
<section aria-label="최근 공지사항">
<h2>최근 공지사항</h2>
...
</section>
<!-- 또는 -->
<section aria-labelledby="notice-heading">
<h2 id="notice-heading">최근 공지사항</h2>
...
</section>
<!-- generic이 되는 section — 랜드마크에 등록되지 않음 -->
<section>
<h2>최근 공지사항</h2>
...
</section><!-- banner role -->
<body>
<header>...</header>
<!-- generic role (banner가 아님) -->
<body>
<article>
<header>...</header> ← 여기서는 그냥 generic
</article>구분 | <div> · <span> | 시맨틱 태그 |
의미 | 없음 (순수 컨테이너) | 콘텐츠 역할을 명시 |
기본 스타일 | 없음 | 브라우저마다 기본 스타일 존재 (<h1>의 font-size 등) |
ARIA role | 없음 (generic) | 암묵적 role 자동 부여 |
키보드 접근성 | 없음 | <button>, <a> 등은 기본으로 포커스 가능 |
SEO 영향 | 낮음 | <h1>, <article>, <main> 등은 크롤러가 특별히 처리 |
