도감의 반대편 카드. 모든 다른 카드가 시맨틱 가치를 다룬다면 — 이 카드는 의미가 없는 두 태그가 언제 정당한가를 다룬다.
HTML 분류:
<div>: flow content. sectioning content 아님. 시맨틱 0.<span>: phrasing content. 인라인 generic.- 둘 다 ARIA landmark 아님. generic role.
WHATWG 명세 인용: "The div element has no special meaning at all. Authors are strongly encouraged to view the div element as an element of last resort."
SEO 관점에서 div는 시맨틱 0. 검색엔진이 div 안 콘텐츠를 본문인지 사이드바인지 광고인지 모른다. 적절한 시맨틱 태그(main, article, section, nav)가 항상 SEO에 더 좋다.
GEO 관점에서 AI가 div를 generic 컨테이너로 인식. 페이지 구조 추출 시 div가 많은 페이지는 추측에 의존. AI 인용 가능성 ↓.
A11y 관점에서 div는 스크린리더가 발화 안 함. landmark 점프에도 안 잡힘. 사용자가 어떤 영역인지 인지하는 모든 단서가 사라진다.
자주 보는 안티패턴:
- 시맨틱 있는데 div — 가장 흔한 div soup. 시리즈 16편이 거의 모든 카드에서 짚은 그 패턴. 적절한 시맨틱 태그를 먼저 시도, 정말 없을 때만 div.
- div onClick으로 button·a 흉내 — 시리즈 #1의 핵심 안티패턴. button 태그 한 줄로 해결될 동작을 div + role + tabindex + onKeyDown 수십 줄로 흉내. 거의 항상 깨진다.
- span에 role 박기 — span은 인라인 generic. role을 박을 정도면 적절한 시맨틱 태그가 있다 (button, a, label 등).
- div 4-5단 중첩 — div soup의 극단. CSS grid·flex로 층이 줄어드는 경우가 많음. div가 4단 넘으면 한 번 재고.
언제 div가 정당한가 (5가지):
- CSS layout wrapper — grid·flex 컨테이너. 시맨틱은 자식들이 담당하고 div는 디자인만.
- JS hook —
data-component,data-testid같은 속성으로 JS가 식별. 시맨틱이 아닌 기술적 hook. - Style scope — 특정 시각 스타일만 적용하는 영역. 시맨틱하게 묶을 이유가 없을 때.
- Group 없는 그룹화 — 시각적으로 묶이지만 시맨틱 의미가 없는 경우. section·article 같은 시맨틱이 어색할 때.
- 3rd-party 임베드 — iframe·embed의 wrapper. div가 시맨틱 손실 없이 wrapping만.
언제 span이 정당한가 (3가지):
- 시각 강조 (시맨틱 아닌) —
<span class="text-red-500">금액</span>같이 시각만 변경. 의미 강조는 em·strong. - 인라인 wrapper — 텍스트 일부분을 스타일·이벤트로 감쌀 때.
- 다국어 인라인 —
<span lang="en">English</span>같이 인라인 언어 전환.
div soup의 대안 결정 트리:
이 div가...
페이지의 주요 콘텐츠 영역? → <main>
독립적 콘텐츠 단위? → <article>
주제별 그룹? → <section>
내비? → <nav>
보조 콘텐츠? → <aside>
헤더? → <header>
푸터? → <footer>
검색 인터페이스? → <search>
form 그룹? → <fieldset>
정의 그룹? → <dl>
리스트 그룹? → <ul> or <ol>
그림+캡션? → <figure>
인터랙티브? → <button>, <a>, <details>
그 외 — 의미 없는 wrapping → <div> OK
도감의 다른 카드와의 관계 — 이 카드가 반대편 짝. 시리즈 16편과 도감 60+편이 시맨틱 옵션을 깊이 다뤘다면 — 이 카드는 시맨틱이 정말 없을 때의 정답을 다룬다. 두 카드 묶음이 완전한 의사결정 매뉴얼.
한국 프론트엔드 현장 — div 남발은 Vue/React 시작점에서 학습된 습관. JSX의 <div>...</div>가 가장 가까운 wrapping. 점진적으로 시맨틱 태그로 옮겨가는 게 모던 한국 사이트의 진화 방향.