Semantic sections
header, nav, main, article, section, aside, footer — and friends. When to use which, and when div is still the right call.
If you opened any web page from 2008 and looked at the source, you would see a forest of <div> tags. <div class="header">, <div class="navigation">, <div class="article">, <div class="footer">. Modern HTML gives you real elements with those names — <header>, <nav>, <article>, <footer>. They look like a stylistic upgrade. They are actually a bigger deal than that.
This lesson is about a small family of elements collectively called semantic sections. Semantic means "having to do with meaning". These elements describe what a chunk of the page is — not what it looks like. Used right, they make a page far easier to read for screen readers, search engines, and the next developer who opens your file.
Why semantic elements exist
Imagine a long book with no chapters, no titles, no table of contents — just one continuous stream of text. You can read it cover to cover, but you cannot skim, cannot find "the part about pricing", cannot jump back to where you were. Every page of HTML written entirely in <div>s is that book.
Semantic elements add an outline to the page. A screen reader can announce "you are inside the navigation, with five links" — if you wrap your nav in <nav>. A search engine can pull out the main content and ignore the sidebar — if you wrap them in <main> and <aside>. A "skip to main content" link can do its job — if there is a <main> to skip to.
The visible page looks identical whether you used <div> or <header>. Browsers style them the same by default. But every tool that reads the HTML — assistive tech, search engines, reader-mode views, future automation — gets a richer picture. That is the payoff. The cost is roughly zero: changing <div class="header"> to <header> is a one-character difference.
<div class="navigation"> to <nav> on your site. Visual appearance does not change. What practical benefit have you actually gained?The shape of a page
Most pages share a rough top-to-bottom shape: a banner at the top, a navigation bar, the main content, maybe a sidebar, and a footer at the bottom. HTML has dedicated elements for each region.
<body>
<header>
<h1>Bramble Bakery</h1>
<nav>
<a href="/">Home</a>
<a href="/menu">Menu</a>
<a href="/contact">Contact</a>
</nav>
</header>
<main>
<article>
<h2>Sourdough fundamentals</h2>
<p>Patience is the main ingredient...</p>
</article>
<aside>
<h3>Latest from the oven</h3>
<p>A new rye loaf, baking Saturdays.</p>
</aside>
</main>
<footer>
<p>© 2026 Bramble Bakery</p>
</footer>
</body>Reading top to bottom: <header> is the top of the page (logo and title), <nav> is a navigation block, <main> wraps the unique content of this page, <article> is one self-contained piece of writing, <aside> is sidebar-style related content, and <footer> is the closer at the bottom.
A few rules pin these down:
- Use exactly one
<main>per page. It marks the unique content — the part that changes from page to page. Repeating elements like the global header, sidebar, and footer go outside<main>. <header>and<footer>are not unique. The page has a top-level header and footer, but each<article>can also have its own header (with the title and byline) and footer (with the publish date or share buttons).<nav>is for major navigation. A short list of "previous / next" links inside an article does not need a<nav>. The site's main menu does.
A useful picture: think of the page as a building. <header> is the lobby, <nav> is the directory on the wall, <main> is the room you actually came to visit, <aside> is the bulletin board on the side, and <footer> is the guestbook by the exit. A floor in the building (an <article>) can have its own little lobby and exit, but the building has just one main entrance and one main exit.
Article vs section
These two are the most-confused pair in semantic HTML. They look similar, but they answer different questions.
An <article> is a complete, standalone piece of content. The test: could you copy this chunk to another site, drop it onto another page, or share it on its own, and have it still make sense? If yes, it is an article. Blog posts, news stories, comments, product cards, individual forum messages — all articles.
A <section> is a thematic grouping of content inside a larger piece. The test: would the content benefit from a heading? Does it represent a distinct chapter or part of a larger whole? If yes, it is a section.
<article> <h1>How to bake sourdough</h1> <section> <h2>The starter</h2> <p>...</p> </section> <section> <h2>The bulk ferment</h2> <p>...</p> </section> <section> <h2>Shaping and proofing</h2> <p>...</p> </section> </article>
The whole sourdough piece is one <article> — a self-contained tutorial. Inside, three <section>s carve up the chapters. Each section has a heading; without that heading, the section has nothing distinguishing it and you should use a plain <div> instead.
Two more guardrails:
- A
<section>should always have a heading. If you are reaching for<section>but there is no obvious heading for it, you probably want<div>. - Do not nest
<article>s for chapters. A long blog post with three chapters is one article with three sections. Use nested articles only when the inner ones are themselves standalone — like reader comments on a blog post (each comment is its own article).
When you are stuck choosing, ask: "Could this stand on its own?" If yes, <article>. "Is this just one chapter of something bigger?" If yes, <section>. "Is it neither — I just need a wrapper for styling?" Use <div>.
Two more elements round out the family.
An <aside> is content related to the main content but tangential to it. The classic examples are sidebars, pull quotes, glossary callouts, "related articles" lists, and ad slots. The rule of thumb: if you removed the aside, the rest of the content would still make sense. It is adjacent to the main flow, not part of it.
<article> <h1>The chemistry of bread</h1> <p>Fermentation is a slow and forgiving process...</p> <aside> <h3>Glossary</h3> <p><strong>Gluten:</strong> the protein network that gives dough its stretch.</p> </aside> <p>Once the dough has doubled, it's ready to shape...</p> </article>
The glossary aside helps but is not essential. Drop it and the article still reads. That is the aside test.
A <nav> is a region of major navigation links. Major is the operative word. Your global menu is a nav. A table of contents linking to sections of the current page is a nav. A "previous / next" pair at the bottom of a blog post is sometimes a nav. A list of three related links at the bottom of an article is not.
<nav aria-label="Primary"> <ul> <li><a href="/">Home</a></li> <li><a href="/menu">Menu</a></li> <li><a href="/contact">Contact</a></li> </ul> </nav>
The aria-label attribute names this nav for screen readers ("Primary navigation"). When a page has more than one <nav> (a primary one and a secondary one, say), labelling each is what lets a screen reader user pick which to jump to.
Wrapping the links in a <ul> is conventional. Each link is one item in a list of navigation options, so <ul><li> matches the structure even though many designs hide the bullets.
When div is still the answer
After all this, you might be tempted to never write <div> again. Resist. There is a job <div> is uniquely good at: being a wrapper that has no semantic meaning. When you need to group some elements together purely for styling — say, to apply a flexbox layout or a coloured background — and that group is not a header, footer, nav, aside, article, or section, a <div> is the right call.
<article> <h1>Pricing</h1> <div class="pricing-grid"> <!-- pure layout wrapper --> <article class="plan">...</article> <article class="plan">...</article> <article class="plan">...</article> </div> </article>
The outer <div class="pricing-grid"> has no semantic meaning — it is just there to give CSS a hook for laying out the three plan cards in a grid. Each plan card is its own <article> because it is a self-contained block.
If you used <section class="pricing-grid"> instead, you would be claiming the wrapper is a thematic chapter of the article — which is not true; it is just a layout box. <div> is the honest choice. Using a semantic element where none fits is worse than using <div>, because it lies to every tool that reads the HTML.
A short rule: pick the most specific semantic element that truthfully describes the chunk. If none fits, fall back to <div> for grouping or <span> for inline grouping. (<span> is the inline cousin of <div> — same idea, but it goes inside a paragraph instead of around a block.)
<main>?<article>. What is the most accurate critique?