Technical SEO
HTML5 semantic tags: complete guide with examples

HTML5 semantic tags are the foundation of correct page markup: they tell the browser, search engine, and screen reader what is on the page without relying on CSS classes or comments. We cover all key tags, demonstrate correct nesting, common mistakes, and the real impact of semantics on SEO and accessibility.
Before HTML5 the web was a sea of divs and spans with CSS classes like .header, .sidebar, .footer. Search robots and screen readers had to guess what was what. HTML5 introduced semantic tags — elements that carry meaning in themselves, independent of CSS. The <article> tag means self-contained content. The <nav> tag means navigation. The <aside> tag means supplementary content related to the main content but not essential for understanding it.
Structural page tags
HTML5 introduced a set of tags for marking up large regions of the page. They form the document skeleton that browsers, search engines, and assistive technology can traverse without reading CSS.
- <header>
- Introductory content for the nearest sectioning context — the page or a section. At the page level: the site header with logo, navigation, and search. Inside an <article>: the title, metadata, and author. Multiple <header> elements are valid on one page if they belong to different sections.
- <nav>
- A block of navigational links. Not every set of links is <nav> — only major navigation routes: main menu, breadcrumbs, pagination. Footer links to the privacy policy are not <nav>. Screen readers use <nav> for a jump-to-navigation keyboard shortcut.
- <main>
- The unique main content of the page. Only one <main> per document. Content in <main> should not repeat across other pages (headers, footers, and sidebars repeat, so they go outside <main>). Screen readers jump directly to <main> via a keyboard shortcut.
- <footer>
- The closing section of the nearest sectioning context. At the page level: contacts, copyright, links. Inside <article>: author info, tags, last-updated date. Like <header>, it can appear in multiple sections.
- <article>
- Self-contained, independently distributable content: a blog post, news article, forum post, product card, or comment. The key test: if you pull the <article> out of context and publish it standalone, does it make sense? If yes — it is an <article>.
- <section>
- A thematically cohesive part of a document without a more specific tag. Should always have a heading (<h2>–<h6>). If there is no heading, a <div> is probably the right choice. Do not use <section> as a styled <div> replacement.
- <aside>
- Content indirectly related to the main content: callout boxes, sidebars, ad blocks, author bios, related articles. Inside <article>: a note or quote not critical for understanding the main text. At the page level: a side column.
The basic skeleton of any page looks like this — and this is already semantically correct markup:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Page title</title>
</head>
<body>
<header>
<a href="/"><img src="logo.svg" alt="Company name"></a>
<nav aria-label="Main navigation">
<ul>
<li><a href="/blog">Blog</a></li>
<li><a href="/services">Services</a></li>
<li><a href="/contacts">Contacts</a></li>
</ul>
</nav>
</header>
<main>
<!-- Unique page content -->
</main>
<footer>
<p>© 2026 Company name</p>
<nav aria-label="Secondary navigation">
<a href="/privacy">Privacy</a>
<a href="/sitemap">Sitemap</a>
</nav>
</footer>
</body>
</html>Content tags: article, section, h1–h6, p
Structural-level tags set the page regions. Content-level tags describe the nature of the content itself. Let us look at the combination found on every blog page.
<!-- Blog post page -->
<main>
<article>
<header>
<h1>How to choose the right HTML tag</h1>
<p>Published: <time datetime="2026-05-22">22 May 2026</time></p>
<address>
By: <a rel="author" href="/authors/pavlo">Pavel Barushka</a>
</address>
</header>
<section>
<h2>Why semantics matters</h2>
<p>Section text...</p>
</section>
<section>
<h2>Main tags</h2>
<p>Section text...</p>
<aside>
<p>Note: the HTML Living Standard is continuously updated.</p>
</aside>
</section>
<footer>
<p>Tags: <a href="/tags/html">#html</a>, <a href="/tags/seo">#seo</a></p>
</footer>
</article>
<!-- Related articles -->
<aside aria-label="Related articles">
<h2>Also read</h2>
<ul>
<li><a href="/blog/heading-structure">Heading structure</a></li>
<li><a href="/blog/schema-org-json-ld">Schema.org markup</a></li>
</ul>
</aside>
</main>When to use section vs div
The rule is simple: if a block has a semantic name, use <section>. If it exists only for styling or as a JavaScript hook, use <div>.
<!-- CORRECT: section with a heading -->
<section>
<h2>Product benefits</h2>
<ul>
<li>Fast delivery</li>
<li>2-year warranty</li>
</ul>
</section>
<!-- CORRECT: div for styling -->
<div class="cards-grid">
<article>...</article>
<article>...</article>
<article>...</article>
</div>
<!-- WRONG: section with no heading -->
<section class="cards-grid">
<article>...</article>
</section>
<!-- WRONG: div where content has meaning -->
<div id="about">
<!-- The About section — this should be <section> -->
<h2>About us</h2>
<p>...</p>
</div>Media, data and utility tags
HTML5 added tags for specific data types — they give search engines additional signals without needing Schema.org markup.
<figure> and <figcaption>
Self-contained media content with a caption. Images, diagrams, tables, code snippets — anything related to the main text that could be moved or placed in an appendix without losing meaning. <figcaption> is the official caption for a <figure>. Google uses <figcaption> as supplementary image description when analysing images.
<time>
A machine-readable date or time. The datetime attribute in ISO 8601 format lets the search engine determine the publication or event date precisely, regardless of how the date is displayed to the user. Google explicitly recommends using <time> for article dates in Article structured data.
<address>
Contact information for the nearest <article> or the document as a whole. Inside <article>: the author's contact details. At the page level: the organisation's contact information. Do not use <address> for postal addresses outside the context of author or organisation contact information.
<details> and <summary>
A native collapsible widget without JavaScript. <summary> is the visible heading. <details> holds the hidden content. The browser handles open/close automatically. Search engines index the content inside <details> even when it is closed. Perfect for FAQs and spoilers.
<mark>
Highlights text as relevant in the current context — for example, search results or keywords in a quote. Do not confuse with <strong> (importance) and <em> (emphasis). <mark> means 'flagged as relevant', not 'important' or 'styled for decoration'.
<data> and <output>
<data value="42">Forty-two</data> links human-readable text to a machine-readable value. <output> represents the result of a computation or user action. Both tags are rare on content sites but essential in web apps with forms and calculators.
<figure> tag with a caption:<!-- figure + figcaption for an image -->
<figure>
<img
src="/images/html5-structure.webp"
alt="Diagram of the semantic structure of an HTML5 page"
width="800" height="450"
>
<figcaption>Fig. 1 — Typical semantic structure of an HTML5 document</figcaption>
</figure>
<!-- figure + figcaption for code -->
<figure>
<pre><code class="language-html"><article>...</article></code></pre>
<figcaption>Example: minimal article markup</figcaption>
</figure>
<!-- time with datetime attribute -->
<p>
Article updated:
<time datetime="2026-05-22T10:30:00+03:00">22 May 2026</time>
</p>
<!-- details + summary (FAQ without JS) -->
<details>
<summary>What is semantic HTML?</summary>
<p>Markup where each tag conveys the meaning of the content,
not just its visual appearance.</p>
</details>
<!-- mark for search highlighting -->
<p>Results for "<mark>semantic tags</mark>" — 42 articles</p>Nesting and combinations: real-world examples
The semantic power of HTML5 is revealed not in individual tags but in their correct combination. Let us walk through typical page architectures.
Blog listing page
<main>
<header>
<h1>SEO blog</h1>
<p>Practical articles on website promotion</p>
</header>
<!-- Article list — each card is an article -->
<section aria-label="Article list">
<article>
<header>
<h2><a href="/blog/semantic-html5">HTML5 semantic tags</a></h2>
<p>
<time datetime="2026-05-22">22 May 2026</time>
· <span>18 min read</span>
</p>
</header>
<p>HTML5 semantic tags are the foundation of correct page markup...</p>
<footer>
<a href="/blog/semantic-html5">Read more</a>
</footer>
</article>
<article>
<header>
<h2><a href="/blog/heading-structure">Heading structure</a></h2>
<p>
<time datetime="2026-04-10">10 April 2026</time>
· <span>12 min read</span>
</p>
</header>
<p>One H1 per page. H2 divides content into sections...</p>
<footer>
<a href="/blog/heading-structure">Read more</a>
</footer>
</article>
</section>
<!-- Pagination -->
<nav aria-label="Pagination">
<a href="?page=1" aria-current="page">1</a>
<a href="?page=2">2</a>
<a href="?page=3">3</a>
</nav>
</main>Product card with reviews
<main>
<article itemscope itemtype="https://schema.org/Product">
<!-- Product main area -->
<header>
<h1 itemprop="name">SoundMax Pro Wireless Headphones</h1>
<p itemprop="description">40 hours of battery life, active noise cancellation...</p>
</header>
<!-- Product image -->
<figure>
<img
src="/products/soundmax-pro.webp"
alt="SoundMax Pro wireless headphones — front view"
itemprop="image"
width="600" height="600"
>
<figcaption>SoundMax Pro in three colours: black, white, blue</figcaption>
</figure>
<!-- Price -->
<section aria-label="Price and purchase">
<p>
<data value="129" itemprop="price">$129</data>
</p>
<button type="button">Add to cart</button>
</section>
<!-- Specs -->
<section>
<h2>Specifications</h2>
<dl>
<dt>Battery life</dt><dd>40 hours</dd>
<dt>Connection</dt><dd>Bluetooth 5.3</dd>
<dt>Weight</dt><dd>250 g</dd>
</dl>
</section>
<!-- Reviews — each review is an article inside article -->
<section aria-label="Customer reviews">
<h2>Reviews</h2>
<article>
<header>
<strong>Anna K.</strong>
<time datetime="2026-04-15">15 April 2026</time>
</header>
<p>Excellent headphones, clean sound. The noise cancellation works brilliantly.</p>
</article>
<article>
<header>
<strong>Michael R.</strong>
<time datetime="2026-03-28">28 March 2026</time>
</header>
<p>The 40-hour claim is real. Took them on a business trip and they lasted the week.</p>
</article>
</section>
</article>
</main>Landing page with sections and sidebar
<body>
<header>
<nav aria-label="Main navigation">
<!-- logo + menu -->
</nav>
</header>
<main>
<!-- Hero section -->
<section aria-labelledby="hero-title">
<h1 id="hero-title">SEO promotion for your business</h1>
<p>We grow organic traffic with guaranteed results</p>
<a href="#contacts" role="button">Get a free audit</a>
</section>
<!-- Services -->
<section>
<h2>Our services</h2>
<ul role="list">
<li>
<article>
<h3>Technical audit</h3>
<p>Full technical health check of your site...</p>
</article>
</li>
<li>
<article>
<h3>Content strategy</h3>
<p>Keyword universe and content calendar...</p>
</article>
</li>
</ul>
</section>
<!-- Main content + sidebar -->
<div class="layout-two-col">
<section>
<h2>Case studies</h2>
<!-- ... -->
</section>
<aside aria-label="Contact us">
<h2>Get in touch</h2>
<address>
<p>Email: <a href="mailto:[email protected]">[email protected]</a></p>
<p>Telegram: <a href="https://t.me/seohead">@seohead</a></p>
</address>
</aside>
</div>
</main>
<footer>
<nav aria-label="Site map">
<ul>
<li><a href="/blog">Blog</a></li>
<li><a href="/glossary">Glossary</a></li>
</ul>
</nav>
<p><small>© 2026 seohead.tech</small></p>
</footer>
</body>Multiple <nav> elements: breadcrumbs and pagination
<!-- Multiple <nav> elements are fine — distinguish them with aria-label -->
<!-- Breadcrumbs -->
<nav aria-label="Breadcrumbs">
<ol>
<li><a href="/">Home</a></li>
<li><a href="/blog">Blog</a></li>
<li aria-current="page">HTML5 semantic tags</li>
</ol>
</nav>
<!-- Main navigation inside <header> -->
<nav aria-label="Main navigation">
<ul>
<li><a href="/blog" aria-current="page">Blog</a></li>
<li><a href="/services">Services</a></li>
</ul>
</nav>
<!-- Pagination at the end of a listing -->
<nav aria-label="Blog pages">
<a href="?page=1" rel="prev" aria-label="Previous page">←</a>
<a href="?page=1">1</a>
<span aria-current="page">2</span>
<a href="?page=3">3</a>
<a href="?page=3" rel="next" aria-label="Next page">→</a>
</nav>
<!-- In-page table of contents -->
<nav aria-label="Article contents">
<ol>
<li><a href="#structural-tags">Structural tags</a></li>
<li><a href="#content-tags">Content tags</a></li>
<li><a href="#nesting-examples">Nesting examples</a></li>
</ol>
</nav>SEO impact: what the search engine actually gets
Semantic markup directly affects how Googlebot understands, indexes, and presents a page in search results. Here are the specific mechanisms.
Identifying main content
Google uses <main> to identify the primary content of a page. Content in the header, footer, and <aside> receives less ranking weight. If all text sits inside <div class="main">, Google spends extra resources figuring out the structure.
Date and author attribution
<time datetime="2026-05-22"> gives Google a precise publication date, which influences freshness assessment. <address> with rel="author" links the article to the author. Both signals feed into rich snippet generation in search results.
Rich results
<details> + <summary> content is indexed by Google and can appear as expandable blocks in search results (People Also Ask). <figure> + <figcaption> influence image indexing and how images appear in Google Images.
Internal linking
Links inside <nav> carry a navigational context. Links inside <article> carry a content context. Googlebot accounts for a link's position on the page when evaluating its weight. A link from the main body of an <article> is worth more than a link from an <aside>.
Common mistakes in semantic markup
Most mistakes come from div-first muscle memory or from misunderstanding what a tag is actually for.
<!-- MISTAKE 1: <section> instead of <div> for styling -->
<section class="flex-wrapper"> <!-- no heading = not section -->
<img src="photo.jpg" alt="">
</section>
<!-- CORRECT -->
<div class="flex-wrapper">
<img src="photo.jpg" alt="Photo description">
</div>
<!-- MISTAKE 2: <article> for a card without standalone meaning -->
<article class="feature-card">
<span class="icon">⚡</span>
<h3>Fast delivery</h3>
</article>
<!-- CORRECT: a benefits card is li or div, not article -->
<li class="feature-card">
<span class="icon" aria-hidden="true">⚡</span>
<h3>Fast delivery</h3>
</li>
<!-- MISTAKE 3: <header> as a synonym for <div class="header"> -->
<header class="section-header">
<h2>Our advantages</h2>
</header>
<!-- CORRECT: use <header> only when a section has an introductory group -->
<section>
<h2>Our advantages</h2> <!-- h2 directly, no header wrapper -->
...
</section>
<!-- MISTAKE 4: two <main> elements -->
<main>Primary content</main>
<main>Also important content</main> <!-- invalid! -->
<!-- CORRECT: one <main>, supplementary content in <aside> -->
<main>Primary content</main>
<aside>Supplementary content</aside>
<!-- MISTAKE 5: <address> for an office address in body text -->
<address>1 High Street, London</address> <!-- not in an author/org context -->
<!-- CORRECT -->
<p>Office address: 1 High Street, London</p>
<!-- or in footer as site contact information: -->
<footer>
<address>
<a href="mailto:[email protected]">[email protected]</a>
</address>
</footer>Another frequent problem is missing or empty alt attributes. Images inside <figure> must have either a meaningful alt or alt="" (if the image is decorative and described by <figcaption>). Never omit the alt attribute entirely — it violates accessibility standards and HTML validation.
<!-- Decorative image: empty alt, figcaption describes it -->
<figure>
<img src="chart.png" alt="" role="presentation">
<figcaption>Organic traffic growth over 6 months: +340%</figcaption>
</figure>
<!-- Informative image: full alt text -->
<figure>
<img
src="html5-tags-map.png"
alt="Map of HTML5 semantic tags: header, nav, main, article, section, aside, footer"
>
<figcaption>Fig. 2 — Complete map of HTML5 semantic elements</figcaption>
</figure>
<!-- Mistake: no alt at all -->
<img src="diagram.png"> <!-- invalid! -->