From "div soup" to meaningful tags
For years, pages were built by stacking <div> for everything: the header,
the menu, the content, the footer... The affectionate name for this is div
soup. The browser displayed it just fine, but neither screen readers nor search
engines could tell what each thing was. To a machine, a <div class="nav">
isn't a menu: it's just one more anonymous box floating in the soup.
Semantic HTML gets you out of there: it uses tags whose name describes their function. They barely change how things look, but they do add meaning to the structure. And that unlocks two huge things: accessibility and SEO. Same looks, a lot more brain behind them.
The main regions (landmarks)
These tags define landmarks: zones that assistive technology can list and jump to directly.
<body>
<header>
<h1>My magazine</h1>
<nav>
<a href="/">Home</a>
<a href="/articles">Articles</a>
</nav>
</header>
<main>
<article>
<h2>How to cook pasta</h2>
<p>Article content...</p>
</article>
<aside>
<h2>Related articles</h2>
<p>...</p>
</aside>
</main>
<footer>
<p>© 2026 My magazine</p>
</footer>
</body>
<header>: the header of the page (or of a section). It usually holds the logo, the title and the main navigation.<nav>: a navigation block. Reserved for the important menus, not for just any group of links.<main>: the page's main, unique content. Only one per page, and it must not contain repeated headers, footers or sidebars.<footer>: the footer: credits, legal notices, secondary links.
Content sections
<article>: a self-contained piece of content that would make sense on its own (a news item, a blog post, a comment, a product card). The test: could you pull it out into an RSS reader and would it still make sense?<section>: a thematic section of the document, usually with its own heading. It groups related content that is not necessarily self-contained.<aside>: content tangential or complementary to the main one: a sidebar, a "did you know..." box, related advertising.
Practical rule: if you hesitate between
<section>and<div>, ask yourself whether the block deserves its own heading. If it does, it is probably a<section>. If you are only grouping it to hang a style on it,<div>is still your friend: not everything has to be semantic, but whatever means something should be.
Small inline semantic tags
<figure>and<figcaption>: group illustrative content (an image, a chart, a code snippet) with its caption.
<figure>
<img src="chart.png" alt="Sales per quarter in 2025" />
<figcaption>Figure 1. Sales grew by 12%.</figcaption>
</figure>
<time>: marks a date or time in a machine-readable way with thedatetimeattribute.
<p>Published on <time datetime="2026-06-22">June 22, 2026</time>.</p>
<mark>: highlights relevant text in its context (for example, the searched terms within a result).
<p>The result contains the word <mark>semantics</mark>.</p>
Why it really matters
- Accessibility: someone using a screen reader can ask for a "list of
regions" and jump straight to the
<main>or the<nav>, without sitting through the header on every page. Div soup offers not a single one of those shortcuts. - SEO: search engines understand the hierarchy and importance of the
content better. An
<article>with its<h2>and its<time>shouts "this is a dated news item" at Google; a<div>stays silent. - Maintainability: the code reads like prose. Six months from now,
<nav>will tell you far more than<div class="menu-top-v2">.
⚠️ Classic trap: reaching for
<div>for everything out of habit. Before you write one, ask whether a tag already exists that says what that block is. Almost always, one does.