PureDevTools

HTML Semantic Elements Reference

Complete HTML5 semantic elements cheat sheet — lookup any element, understand accessibility implications, validate semantic structure

All processing happens in your browser. No data is sent to any server.
|32 elements

Your site is a wall of <div>s. Screen readers announce every section as “group” instead of “navigation,” “main content,” or “article.” Google can’t distinguish your sidebar from your main content. You know <nav>, <main>, <article>, and <aside> exist, but you’re not sure when <section> is better than <article>, whether <header> can be nested inside <article>, or which elements actually map to ARIA landmarks. The spec definitions are vague, and getting it wrong means your accessibility audit fails.

Why This Reference (Not the HTML Input Types Reference)

PureDevTools has an HTML Input Types Reference for form elements. This reference covers structural semantic elements — document structure (header, nav, main, aside, footer, article, section), text content, inline semantics, interactive elements, and grouping. Every element includes its purpose, when to use it, accessibility implications, and code examples.

HTML Semantic Elements Reference

HTML semantic elements are elements that carry meaning — they tell the browser, search engine, and assistive technology what the content is, not just how it looks. Using the right element for the right job is one of the highest-impact improvements you can make to HTML: it improves SEO, enables accessibility features, and makes your code self-documenting.

<!-- Non-semantic: a developer must read the code to understand the structure -->
<div id="header">
  <div class="nav">...</div>
</div>
<div class="main-content">
  <div class="article">...</div>
</div>

<!-- Semantic: the structure is self-evident -->
<header>
  <nav aria-label="Primary">...</nav>
</header>
<main>
  <article>...</article>
</main>

Why Semantic HTML Matters

Accessibility: Screen readers use semantic elements to build a navigation tree. Users can jump directly to landmarks (<main>, <nav>, <aside>, <footer>). Without semantics, keyboard-only and screen reader users must read every element to understand the page.

SEO: Search engine crawlers use semantic structure to understand content hierarchy, identify the primary topic (<h1>, <main>), recognize navigational boilerplate (<nav>, <footer>), and parse structured content (<article>, <time>, <address>).

Maintainability: <header> is clearer than <div id="header">. The code communicates intent, reducing cognitive load for the next developer (or future you).

Browser features: Some elements provide free behavior: <details>/<summary> for disclosure widgets, <dialog> for modals with focus management, <input type="search"> for search-specific UX.

Document Structure Elements

<header> — Page or Section Header

The <header> element represents introductory content. As a direct child of <body>, it is the site-wide page header and maps to the ARIA banner landmark. When nested inside <article>, <section>, or similar, it is the header for that section only.

<!-- Site-wide header (banner landmark) -->
<header>
  <a href="/" class="logo">MyApp</a>
  <nav aria-label="Primary navigation">
    <ul>
      <li><a href="/features">Features</a></li>
      <li><a href="/docs">Documentation</a></li>
    </ul>
  </nav>
</header>

<!-- Article-level header (no landmark role) -->
<article>
  <header>
    <h2>Article Title</h2>
    <time datetime="2024-01-15">January 15, 2024</time>
  </header>
  <p>Article content...</p>
</article>

<nav> marks major navigation blocks — primary navigation, breadcrumbs, pagination, table of contents. Not every group of links needs to be a <nav>. When multiple <nav> elements exist, give each a unique aria-label so screen reader users can distinguish them.

<nav aria-label="Primary navigation">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/products">Products</a></li>
  </ul>
</nav>

<nav aria-label="Breadcrumb">
  <ol>
    <li><a href="/">Home</a></li>
    <li><a href="/blog">Blog</a></li>
    <li aria-current="page">How to Use Semantic HTML</li>
  </ol>
</nav>

<main> — Primary Content

There should be exactly one visible <main> element per page. It wraps the content that is unique to the current page — everything except the header, navigation, and footer. The “skip to main content” accessibility link targets <main>. This landmark is critical for keyboard and screen reader users to bypass repetitive navigation.

<body>
  <header><!-- site header --></header>
  <nav><!-- navigation --></nav>

  <main>
    <h1>Getting Started with Semantic HTML</h1>
    <p>All unique page content goes here...</p>
  </main>

  <footer><!-- site footer --></footer>
</body>

<aside> — Tangential Content

<aside> represents content tangentially related to the main content — sidebars, pull quotes, related articles, advertising, author bios. A top-level <aside> maps to the ARIA complementary landmark.

A top-level <footer> maps to the ARIA contentinfo landmark. Typically contains copyright notices, related links, and legal information. Can also be nested inside <article> or <section> as a section-level footer.

<article> — Self-Contained Composition

<article> represents content that makes sense independently — blog posts, news articles, comments, product cards, social media posts. Ask: “Could this be the only thing on the page and still make sense?” If yes, use <article>.

<section> — Thematic Grouping

<section> groups thematically related content that forms part of a larger document. When given an accessible name via aria-labelledby, it becomes a named region landmark. Rule of thumb: if you cannot give a meaningful heading to a <section>, it probably should be a <div>.

Text Content Elements

Headings (<h1><h6>)

Headings define the document outline. Use them to structure content hierarchically — never for visual styling. Key rules:

<h1>HTML Semantic Elements Reference</h1>
  <h2>Document Structure</h2>
    <h3>The header Element</h3>
    <h3>The nav Element</h3>
  <h2>Text Content</h2>
    <h3>Headings</h3>
    <h3>Paragraphs</h3>

<blockquote> — Extended Quotations

Use <blockquote> for extended quoted passages from external sources. The cite attribute holds the URL of the source (not displayed by browsers — use a visible <cite> element for attribution).

<blockquote cite="https://www.w3.org/TR/html52/">
  <p>
    The <code>blockquote</code> element represents content
    quoted from another source.
  </p>
  <footer>— <cite>HTML 5.2 Specification</cite></footer>
</blockquote>

<figure> and <figcaption> — Referenced Figures

<figure> wraps self-contained content (images, code examples, charts, tables) that is referenced from the main flow. <figcaption> provides the caption and should always be included.

<figure>
  <img
    src="/charts/performance.png"
    alt="Line chart showing LCP improving from 4.2s to 1.8s after optimization"
  />
  <figcaption>
    Figure 2: LCP improvement after enabling content-visibility: auto
  </figcaption>
</figure>

<figure>
  <pre><code>const result = arr.map(x => x * 2);</code></pre>
  <figcaption>Using Array.map() to double each value</figcaption>
</figure>

<details> and <summary> — Disclosure Widgets

<details> is a native disclosure widget — no JavaScript needed for basic expand/collapse functionality. The <summary> provides the visible toggle text.

<details>
  <summary>Why use semantic elements?</summary>
  <p>
    Semantic elements improve accessibility, SEO, and code readability.
    They provide free behavior (landmarks, keyboard navigation) and
    communicate structure to any parser.
  </p>
</details>

<!-- Open by default -->
<details open>
  <summary>Advanced configuration</summary>
  <label>
    <input type="checkbox" name="verbose" />
    Enable verbose logging
  </label>
</details>

<mark> — Highlighted Text

<mark> highlights text for reference — like search keywords in search results. It is not for general emphasis.

<!-- Search result with query "semantic HTML" highlighted -->
<p>
  <mark>Semantic HTML</mark> elements carry meaning beyond visual presentation.
</p>

<time> — Dates and Times

Always use the datetime attribute with an ISO 8601 formatted value. The human-readable text can be in any format; the machine-readable format is in datetime.

<p>Published <time datetime="2024-01-15">January 15, 2024</time>.</p>
<p>Event starts at <time datetime="2024-03-20T18:30">6:30 PM, March 20</time>.</p>
<p>Duration: <time datetime="PT45M">45 minutes</time>.</p>

<address> — Contact Information

<address> is specifically for contact information related to the document’s author or the nearest <article>’s author — not for general postal addresses in content.

Inline Semantic Elements

<abbr> — Abbreviations

<p>
  Use <abbr title="Hypertext Markup Language">HTML</abbr>
  semantic elements to improve
  <abbr title="Search Engine Optimization">SEO</abbr>.
</p>

<cite> — Creative Work Titles

<cite> marks the title of a creative work. It is not for person names — only work titles.

<p>Read <cite>The Pragmatic Programmer</cite> for more advice.</p>
<blockquote>
  <p>Any fool can write code a computer can understand.</p>
  <footer>— <cite>Refactoring, Martin Fowler</cite></footer>
</blockquote>
ElementUse forExample
<code>Code fragments, element/property namesAdd <code>display: flex</code>
<kbd>Keyboard input, keys, commandsPress <kbd>Ctrl</kbd>+<kbd>S</kbd>
<samp>Program output, error messagesError: <samp>Cannot find module</samp>
<var>Variable names, math variablesIterate over <var>items</var>

<em> vs <strong> vs <i> vs <b>

This is one of the most misunderstood areas of HTML semantics:

ElementMeaningDefault rendering
<em>Stress emphasis (changes meaning of sentence)Italic
<strong>Strong importance, seriousness, urgencyBold
<i>Different voice, technical terms, stylistic italicsItalic
<b>Stylistically bold text, keywords, no special importanceBold
<!-- em: the stressed word changes the sentence's meaning -->
<p>You should <em>always</em> test your code.</p>

<!-- strong: serious importance or urgency -->
<p><strong>Warning:</strong> This action cannot be undone.</p>

<!-- i: foreign term, technical term — different voice, not emphasis -->
<p>The term <i>mise en place</i> is central to professional cooking.</p>

<!-- b: keyword highlight, no extra importance -->
<p>The <b>quick sort</b> algorithm has O(n log n) average complexity.</p>

<dfn> — Definition

Mark the defining instance of a term:

<p>
  The <dfn id="def-landmark">landmark</dfn> is a
  recognizable navigational region mapped to an ARIA role.
  Screen readers list all landmarks so users can jump directly to them.
</p>

Interactive Elements

<dialog> — Modal Dialogs

Prefer the native <dialog> element over custom ARIA modal patterns. It provides:

<dialog id="delete-dialog" aria-labelledby="dialog-title">
  <h2 id="dialog-title">Confirm Delete</h2>
  <p>This action cannot be undone. Are you sure?</p>
  <menu>
    <li><button autofocus type="button" id="cancel">Cancel</button></li>
    <li><button type="button" id="confirm">Delete</button></li>
  </menu>
</dialog>

<script>
  document.getElementById('delete-dialog').showModal();
</script>

<search> — Search Landmark

The <search> element (HTML 2023) creates a search landmark region. Previously required <div role="search">. Maps to ARIA search landmark.

<search aria-label="Site search">
  <form action="/search" method="get">
    <label for="q">Search documentation</label>
    <input type="search" id="q" name="q" placeholder="Enter query..." />
    <button type="submit">Search</button>
  </form>
</search>

Grouping Elements

<hgroup> — Heading with Subtitle

Groups a heading with a subtitle or tagline. Only the h1–h6 element inside contributes to the document outline:

<hgroup>
  <h1>The HTML Reference</h1>
  <p>A complete guide to semantic HTML5 elements</p>
</hgroup>

Common Semantic Mistakes

Using <div> as a Structural Landmark

The most common mistake. Always replace structural <div> containers with their semantic equivalent:

WrongRightLandmark Role
<div id="header"><header>banner
<div id="nav"><nav>navigation
<div id="main"><main>main
<div id="footer"><footer>contentinfo
<div id="sidebar"><aside>complementary

Using <br><br> for Paragraph Spacing

Double <br> creates no paragraph structure. Screen readers cannot distinguish paragraph breaks created with <br>. Use separate <p> elements.

Skipping Heading Levels

Jumping from <h1> to <h3> without <h2> breaks the document outline and confuses screen reader navigation. Heading levels must be sequential without gaps.

Multiple <h1> Elements

One <h1> per page for the primary topic. While the HTML5 outline algorithm allowed multiple <h1> per sectioning element, this was never implemented by browsers or supported by screen readers — use h2h6 for section headings.

Frequently Asked Questions

What is the difference between <article> and <section>? <article> is self-contained content that could be independently redistributed (blog post, product card, comment). <section> is a thematic grouping within a larger document that is not independently meaningful. If the content could stand alone without context, use <article>. If it is a part of a larger whole, use <section>.

Do I need ARIA roles if I use semantic elements? Many semantic elements have implicit ARIA roles and do not need role="" added. <header> is banner, <nav> is navigation, <main> is main. However, you still need ARIA attributes like aria-label (to distinguish multiple navs), aria-current (for current page in breadcrumbs), and aria-labelledby (to name dialogs and regions).

When should I use <div> vs a semantic element? Use <div> when you need a container for styling or scripting purposes with no semantic meaning — a layout grid wrapper, an animation container, a style boundary. Use semantic elements when the container has meaning: structural (header, nav, main), compositional (article, section), or interactive (dialog, details).

Is <section> with an aria-label a landmark? Yes. A <section> with an accessible name (via aria-label or aria-labelledby) maps to the ARIA region landmark. Without a name, it is not a landmark and is just a generic grouping element.

What about <div role="..."> vs native elements? Always prefer native semantic elements over ARIA roles on divs. Native elements are more robust, require less custom JavaScript, have better browser support, and do not require you to manually manage all the required ARIA attributes and keyboard behavior that native elements provide for free.

Does semantic HTML affect performance? Minimal to zero performance impact. Semantic elements have the same rendering performance as <div>. The real-world impact is on SEO crawl quality, accessibility tree construction, and browser feature availability — not rendering performance.

Related Tools

More HTML & Markdown Tools