HTML basics · 7 / 8
lesson 7

Semantic sections

header, nav, main, article, section, aside, footer — and friends. When to use which, and when div is still the right call.

~ 14 min read·lesson 7 of 8
0 / 8

Before HTML5, every region of a page was a <div> with a class — <div class="header">, <div class="sidebar">, <div class="article">. The browser had no idea which div was the navigation and which was the footer; assistive technology had to guess from class names. HTML5 added a small vocabulary of semantic elements that name those regions directly.

This isn't aesthetic preference. Screen readers expose a "landmarks" navigation mode where users jump straight to main, nav, or footer. Search engines use the structure to identify the primary content. Reader-mode browsers strip everything that isn't <article> or <main>. None of that fires on <div class="header">.

Page-level landmarks

Four elements carry the load:

  • <header> — introductory content for the page or for a section. Most often the site's banner: logo, top-level nav, search. Inside an <article>, it's the article's own header (title, byline, date).
  • <nav> — a major block of navigation links. Reserved for the main navigation regions, not every group of links. The site's primary nav, a table of contents, paginated links between articles — yes. Three social-media icons in the footer — no.
  • <main> — the primary content of the document, exclusive of headers, footers, and sidebars. There must be exactly one <main> per page.
  • <footer> — closing content for the page or section. Author info, copyright, related links.
page-skeleton.html
<body>
<header>
  <a href="/"><img src="logo.svg" alt="Acme"></a>
  <nav aria-label="Primary">
    <a href="/products">Products</a>
    <a href="/pricing">Pricing</a>
    <a href="/docs">Docs</a>
  </nav>
</header>

<main>
  <article>
    <h1>Article title</h1>
    <p>...</p>
  </article>
</main>

<footer>
  <p>© 2025 Acme</p>
</footer>
</body>

<header> and <footer> aren't unique. A page can have one outer header, plus an inner header for each <article> — they nest, and the meaning ("introductory content for this sectioning element") still holds.

check your understanding
A page has a banner with a logo and primary nav, then a list of articles each with its own title, date, and author. Where does <header> belong?

Article vs section

The two get confused because both contain headings and nested content. They mean different things.

<article> is self-contained. If you copy it into a different context — an aggregator, an email digest, a social-media unfurl — it still makes sense on its own. Blog posts, news stories, forum threads, product cards on a listing page. The test: would this make sense as the only thing on a page?

<section> is a chapter — a thematic grouping of content that belongs to a larger whole. It needs a heading. A long article might be split into several sections, each covering a sub-topic.

The lazy default <div> doesn't claim either. Reach for <article> when the chunk could stand alone, <section> when it's a labeled subdivision of something larger, and <div> when it's pure styling scaffolding with no semantic claim to make.

article-vs-section.html
<article>
<h1>The HTML parser is more interesting than you'd think</h1>

<section>
  <h2>Tokenization</h2>
  <p>...</p>
</section>

<section>
  <h2>Tree construction</h2>
  <p>...</p>
</section>
</article>
Watch out

Don't use <section> as a fancy <div>. A section without a heading is a smell — you're claiming "thematic grouping" but not labeling the theme. If there's no heading and no clear topic, it's a div.

check your understanding
You're building a homepage with three feature cards (each a short title plus blurb plus icon) and an FAQ that's a list of question/answer pairs. Which mix is closest to right?

Aside, time, address

Three smaller elements with specific jobs:

  • <aside> — content tangentially related to the main flow. A sidebar, a pull quote, a "related articles" block, an ad. Not "anything visually off to the side" — it has to be tangential. A piece of the article's main argument that happens to be in a sidebar is still part of the article.
  • <time> — a date, time, or duration. The datetime attribute carries a machine-readable ISO 8601 value: <time datetime="2025-04-26">April 26th</time>. Crawlers and calendar tools can parse the value without trying to parse the human prose.
  • <address> — contact information for the article's or page's author. Despite the name, it's not for any address — a venue's street address inside a story is just a <p>. It's specifically who to contact about this content, usually inside an article footer.
byline.html
<article>
<header>
  <h1>HTML basics</h1>
  <p>By <address>Ada Lovelace</address>, published
     <time datetime="2025-04-26">26 April 2025</time>.</p>
</header>
...
</article>

details, summary, dialog

Two interactive elements the platform gives you for free.

<details> is a disclosure widget — a collapsed region that opens when you click its summary. <summary> is the always-visible label. The open boolean attribute starts it expanded. No JavaScript required: the open/close is built into the browser.

details.html
<details>
<summary>Why is the parser so forgiving?</summary>
<p>Because the early web's HTML was so sloppy that strict parsers
   would have rendered most of it as error pages...</p>
</details>

<dialog> is a modal or non-modal popup. Open it from JavaScript with dialog.showModal() (modal — backdrop, traps focus) or dialog.show() (non-modal). Close it with dialog.close() or by submitting a form with method="dialog". The browser handles focus trapping, the ::backdrop pseudo-element, and keyboard escape — all the things you'd otherwise build by hand for a modal.

dialog.html
<dialog id="confirm">
<form method="dialog">
  <p>Delete this draft?</p>
  <button value="cancel">Cancel</button>
  <button value="delete">Delete</button>
</form>
</dialog>

<button onclick="document.getElementById('confirm').showModal()">
Delete draft
</button>
check your understanding
You're building a "show details" toggle for an FAQ entry. Which approach is the most platform-aligned?

When div is the right answer

A <div> is a container with no semantic meaning. That isn't a failure; sometimes "no semantic meaning" is the truth. A wrapper element that exists only to apply a CSS grid, or to group two paragraphs for a Tailwind class, has nothing to claim about its content.

Reaching for <section> or <article> when the chunk doesn't actually fit — because "div feels lazy" — pollutes the accessibility tree the same way using a table for layout does. Screen readers will announce a section landmark that doesn't exist, and users navigating by landmarks will end up in a region that has no thematic identity.

The shape of the rule: start with <div> and earn your way up. If the chunk is self-contained content, promote to <article>. If it's a labeled subdivision of a larger article, promote to <section>. If it's the document's main content, promote to <main>. If you can't articulate what makes it more than a styling wrapper, leave it as a div.

check your understanding
You wrap two paragraphs in a container so a CSS grid rule can lay them out as a card. The card has no heading and isn't really a "topic" — just visual grouping. Which element fits?
← prevnext lesson →
KeepLearningcertificate
for completing
HTML basics
0 of 8 read