Semantic HTML Elements
Learn semantic HTML: use header, nav, main, section, article, aside and footer to give your pages meaning, better accessibility and stronger SEO, with a full runnable example and a quiz.
Key takeaways
- Semantic elements describe the MEANING of content, not just its appearance
- header, nav, main, section, article, aside and footer give a page clear structure
- Screen readers and search engines use these tags to understand your page
- Use exactly one <main> per page and one <h1> that names the whole page
- Reach for <div> only when no semantic element fits
Why HTML needs meaning
When you first learn HTML you can build a whole page with nothing but <div> boxes. It works, but every box looks identical to a computer. A browser, a screen reader, or Google's crawler has no idea which <div> is the menu, which is the main story, and which is just decoration. That makes pages harder to navigate for people using assistive technology and harder for search engines to index well.
Semantic HTML fixes this. A semantic element is one whose name describes the meaning of its content. Instead of <div class="nav"> you write <nav>. Instead of <div class="footer"> you write <footer>. The tag itself now carries meaning. This lesson assumes you already know the basics from Introduction to HTML Tags.
The structural elements
HTML5 added a family of elements for the main regions of a page. Here are the ones you'll use constantly:
| Element | Use it for |
|---|---|
<header> | Top of a page or section: logo, title, intro |
<nav> | A block of major navigation links |
<main> | The page's primary, unique content (one per page) |
<section> | A thematic group of content, usually with a heading |
<article> | A self-contained item: blog post, card, comment |
<aside> | Side content: related links, ads, a callout |
<footer> | Bottom of a page or section: copyright, contact |
A useful mental model: these tags are labels for the boxes you used to make with <div>. They draw nothing new on the screen — they add meaning.
How a real page fits together
Think of a typical blog page from top to bottom:
<header> ... site title and tagline ... </header>
<nav> ... main menu links ... </nav>
<main>
<article> ... the actual blog post ... </article>
<aside> ... related posts ... </aside>
</main>
<footer> ... copyright ... </footer>
Notice that <header>, <nav>, <main> and <footer> are siblings — they sit side by side at the top level. The <main> then holds the content that is unique to this page. The header, nav and footer usually repeat across every page of the site; the <main> is what changes.
header and footer can repeat
A subtle but important point: <header> and <footer> are not limited to the page itself. They can also wrap the top or bottom of a <section> or <article>. For example, a blog post can have its own header (title and date) and its own footer (author and tags):
<article>
<header>
<h2>How Plants Make Food</h2>
<p>Published 30 May 2026</p>
</header>
<p>Plants use sunlight to turn water and carbon dioxide into sugar...</p>
<footer>Written by Sam · Tags: biology, science</footer>
</article>
This nesting is perfectly valid and very common.
Headings still matter
Semantic regions and headings (<h1>–<h6>) work together. Every page should have exactly one <h1> that names the whole page. Inside sections and articles, use <h2> and below to build a logical outline. Don't pick a heading level because of its size — pick it for its rank in the hierarchy, then style the size with CSS, as covered in Styling Web Pages with CSS.
A complete worked example
Save this as blog.html and open it in your browser. It's a full, valid page built entirely from semantic elements.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My Science Blog</title>
<style>
body { font-family: sans-serif; margin: 0; line-height: 1.6; }
header.site, footer.site { background: #1e293b; color: white; padding: 16px 24px; }
nav { background: #334155; padding: 12px 24px; }
nav a { color: #cbd5e1; margin-right: 16px; text-decoration: none; }
main { display: flex; gap: 24px; padding: 24px; }
article { flex: 2; }
aside { flex: 1; background: #f1f5f9; padding: 16px; border-radius: 8px; }
</style>
</head>
<body>
<header class="site">
<h1>My Science Blog</h1>
<p>Curious about how the world works.</p>
</header>
<nav>
<a href="#">Home</a>
<a href="#">Articles</a>
<a href="#">About</a>
</nav>
<main>
<article>
<header>
<h2>How Plants Make Food</h2>
<p><time datetime="2026-05-30">30 May 2026</time></p>
</header>
<p>Plants capture sunlight in their leaves and use it to combine
water and carbon dioxide into sugar. This process is called
photosynthesis, and it releases the oxygen we breathe.</p>
<footer>Written by Sam</footer>
</article>
<aside>
<h2>Related</h2>
<ul>
<li><a href="#">Why leaves are green</a></li>
<li><a href="#">The water cycle</a></li>
</ul>
</aside>
</main>
<footer class="site">
<p>© 2026 My Science Blog</p>
</footer>
</body>
</html>
Reading the structure: the page-level <header class="site"> holds the <h1>, the <nav> holds the menu, the <main> splits into the <article> (the post) and an <aside> (related links), and the <footer class="site"> closes the page. Notice the <time> element with a machine-readable datetime — another small semantic touch that helps tools understand your dates.
Try it yourself
- Add a second article. Copy the
<article>block and write a new short post inside the same<main>. Each gets its own<header>and<h2>. - Build a features section. Above the articles, add a
<section>with an<h2>of "Topics" and three short paragraphs. Notice how<section>groups related content with a heading. - Inspect it. Open your browser's developer tools and look at the element tree — you can now read the page's purpose straight from the tag names.
Challenge: Take a page you previously built with only <div>s — perhaps your work from Build a Simple Web Page — and rewrite every box with the correct semantic element. Then check that you have exactly one <main> and one <h1>, and that any leftover <div>s genuinely have no better semantic match.
Quick quiz
Test yourself and earn XP
What does a semantic HTML element describe?
Semantic elements like <nav> or <article> tell the browser what the content MEANS, not how it looks.
How many <main> elements should a page have?
A page should contain exactly one <main>, holding the page's primary, unique content.
Which element is best for a self-contained blog post?
<article> is for a self-contained piece that would make sense on its own, like a blog post or news story.
Where do navigation links belong?
<nav> is the semantic home for major navigation link groups.
When should you use a plain <div>?
Use <div> as a neutral box only when no semantic element describes the content.
FAQ
Not by default. Most semantic elements render the same as a plain <div> visually. The difference is meaning: screen readers, search engines and other tools can understand the structure. You still style everything with CSS.
An <article> is self-contained and would make sense on its own (a blog post, a product card, a comment). A <section> is a thematic grouping of related content inside a page that usually has its own heading, like a 'Features' or 'Reviews' block. If you could syndicate it elsewhere, it's probably an article.
Keep exploring
More in Coding