What are semantic HTML elements and why do they matter?
Semantic elements describe meaning, not appearance: <header>, <nav>, <main>, <article>, <section>, <aside>, <footer>, <button>, <figure>, <time>. They give assistive tech landmarks, give browsers built-in keyboard and focus behavior, give SEO structured content signals, and make code self-documenting. Compare <div class='button'> (zero meaning) to <button> (focusable, click+keyboard, disabled state, form participation).
Definition: Semantic HTML elements convey meaning about their content, not just visual styling. <article> says "this is a self-contained piece of content." <div> says nothing.
The semantic vocabulary
Document structure
<header>— introductory content (site header, article header).<nav>— primary navigation links.<main>— the unique main content of the page (one per page).<article>— self-contained content reusable in isolation (blog post, comment).<section>— a thematic grouping, usually with a heading.<aside>— tangentially related content (sidebar, callout).<footer>— closing content (copyright, links).
Text-level
<time datetime="2026-05-17">— machine-readable dates.<address>— contact info for the nearest<article>or<body>.<figure>/<figcaption>— illustration + caption pair.<mark>— highlighted/marked text.<abbr title="…">— abbreviation with expansion.
Interactive
<button>— action trigger.<a href>— navigation.<details>/<summary>— native disclosure widget.<dialog>— native modal.<input>,<select>,<textarea>with<label>.
Why they matter
1. Accessibility (the big one). Screen readers use semantic elements to build a navigation model:
- "Jump to next landmark" →
<nav>,<main>,<aside>. - "List all headings" →
<h1>–<h6>hierarchy. - "Tab through buttons" →
<button>is focusable;<div onClick>is not (until you manually add tabindex, keyboard handlers, role, focus ring…).
2. Built-in behavior. <button>: focusable, activated by Enter/Space, has disabled and type="submit". <details>: native expand/collapse with zero JS. <dialog>: modal stacking + Escape-to-close. Replicating these correctly in divs takes hundreds of lines.
3. SEO. Search engines weight content in <main>, <article> higher than chrome in <nav> and <footer>. <time datetime> lets crawlers extract publish dates. <h1>–<h6> hierarchy is core to topic understanding.
4. Self-documenting code. Six months later, <article class="post"> tells the next dev what it is. <div class="post"> tells them nothing — and grep-ability is worse.
5. Robustness. Browser default styles for semantic elements are sensible. Reader mode, RSS, print stylesheets, and content extraction tools (Pocket, Instapaper) all key off <article>/<main>. Div soup is invisible to them.
Concrete contrast
<!-- Div soup -->
<div class="card">
<div class="title">My Post</div>
<div class="meta">By Jane, May 2026</div>
<div class="body">…</div>
<div class="btn" onclick="like()">Like</div>
</div>
<!-- Semantic -->
<article>
<h2>My Post</h2>
<p>By Jane, <time datetime="2026-05">May 2026</time></p>
<p>…</p>
<button type="button" onclick="like()">Like</button>
</article>Same visual output. Wildly different experience for screen reader, keyboard, search engine, and reader-mode users.
When to use <div> and <span>
When you need a hook for styling/layout with no semantic meaning. A wrapper for a CSS grid item, a span for inline text color. They're the fallbacks, not the defaults.
Follow-up questions
- •What's the difference between <section> and <article>?
- •When should you use <div> instead of a semantic element?
- •How do <header> and <footer> work inside <article>?
- •What does <main> add beyond a styled <div>?
Common mistakes
- •Using <section> as a generic wrapper — it's for thematic groupings with a heading.
- •Multiple <main> elements on one page — there should be exactly one.
- •Using <h1> for visual sizing on inner sections — use <h2>/<h3> and CSS.
- •<button> styled as a link, or <a> with onClick that doesn't navigate — pick the one matching intent.
- •Forgetting <label for> association on form inputs.
- •Replacing <details>/<summary> with custom JS disclosure that lacks keyboard support.
Performance considerations
- •Semantic elements are identical to <div> at the rendering level — same DOM cost, same paint. Wins are in dev velocity, a11y, and SEO. No runtime perf trade-off.
Edge cases
- •<section> without a heading is a smell — use <div> instead.
- •Nested <article> elements are allowed (e.g., a comment is an <article> inside the post's <article>).
- •<header>/<footer> can appear inside <article> (per-article header/footer) — they're not page-singletons.
- •<nav> isn't required for every group of links — only for primary navigation regions.
- •<dialog> needs polyfill for older browsers (IE, very old Safari).
Real-world examples
- •BBC, NYT, Guardian — heavily semantic article markup for reader mode + SEO.
- •GitHub uses landmarks extensively; VoiceOver users can navigate the file tree, content, and sidebar with single shortcuts.
- •MDN itself is a semantic-HTML showcase.