🏗️ Lesson 9: Semantic HTML
You've learned how to put content on a page — headings, paragraphs, links, images, lists, tables, and forms. Now it's time to give your page meaning. Semantic HTML tells the browser, screen readers, and search engines what each part of your page is, not just what it looks like.
🎯 Learning Objectives
By the end of this lesson, you will be able to:
- Explain the difference between semantic and non-semantic elements
- Use
<header>,<nav>,<main>,<footer>for page-level structure - Use
<article>,<section>, and<aside>for content organization - Choose
<figure>and<figcaption>for illustrated content - Understand when to use
<div>and<span>as generic containers - Restructure your website project with semantic elements
Estimated Time: 45 minutes
Hands-on: You'll refactor your homepage with semantic elements.
📑 In This Lesson
What Is Semantic HTML?
The word "semantic" means "relating to meaning." A semantic element clearly describes its purpose to both the browser and the developer. A non-semantic element tells you nothing about what's inside it.
<!-- Non-semantic — what is this? A header? A sidebar? A footer? -->
<div>
<div>My Website</div>
<div>
<div>Welcome!</div>
<div>This is my page.</div>
</div>
</div>
<!-- Semantic — instantly clear what each part is -->
<header>
<h1>My Website</h1>
</header>
<main>
<h2>Welcome!</h2>
<p>This is my page.</p>
</main>
Both versions look identical in the browser. But the semantic version communicates what each part is — and that matters for three important reasons:
- Accessibility: Screen readers use semantic elements as landmarks. A visually impaired user can jump directly to
<nav>,<main>, or<footer>instead of listening to the entire page from top to bottom. - SEO: Search engines give more weight to content inside
<main>and<article>than content in a generic<div>. They can also distinguish navigation from actual content. - Maintainability: When you (or another developer) read the code six months later,
<header>is instantly understandable.<div class="top-bar-wrapper">requires detective work.
Describes meaning
header, nav, main,
article, section, aside, footer"] A --> C["Non-Semantic
No inherent meaning
div, span"] B --> D["✅ Accessibility
✅ SEO
✅ Readability"] C --> E["Use only when no
semantic element fits"] style A fill:#eff6ff,stroke:#3b82f6,stroke-width:2px,color:#1e293b style B fill:#f0fdf4,stroke:#22c55e,stroke-width:2px,color:#1e293b style C fill:#fef2f2,stroke:#ef4444,stroke-width:2px,color:#1e293b style D fill:#f8fafc,stroke:#64748b,stroke-width:1px,color:#1e293b style E fill:#f8fafc,stroke:#64748b,stroke-width:1px,color:#1e293b
Page-Level Structure
Most web pages share a common layout: a header at the top, navigation links, a main content area, and a footer at the bottom. HTML5 has dedicated elements for each of these:
Site title, logo, intro"] --> B["<nav>
Navigation links"] B --> C["<main>
Primary page content"] C --> D["<footer>
Copyright, links, contact"] style A fill:#eff6ff,stroke:#3b82f6,stroke-width:2px,color:#1e293b style B fill:#fdf4ff,stroke:#a855f7,stroke-width:2px,color:#1e293b style C fill:#f0fdf4,stroke:#22c55e,stroke-width:2px,color:#1e293b style D fill:#fffbeb,stroke:#f59e0b,stroke-width:2px,color:#1e293b
<header>
Represents introductory content, typically at the top of a page or section. A page header usually contains the site name, logo, and primary navigation:
<header>
<h1>My Personal Website</h1>
<p>A place for my projects and writing.</p>
</header>
You can have multiple <header> elements — one for the page, and one inside an <article> or <section>. It doesn't have to be at the top of the page; it just marks introductory content for its parent.
<nav>
Contains a set of navigation links — the main menu, breadcrumbs, or table of contents:
<nav>
<a href="index.html">Home</a>
<a href="about.html">About</a>
<a href="recipe.html">Recipes</a>
<a href="contact.html">Contact</a>
</nav>
Not every group of links is a <nav>. Use it for major navigation blocks — the site menu, sidebar navigation, or pagination. A few links in a paragraph don't need a <nav>.
<main>
Contains the dominant content of the page — the content that's unique to this page and not repeated on other pages (like the sidebar or footer). There should be only one <main> per page:
<main>
<h2>Welcome to My Site</h2>
<p>This is the main content of my homepage...</p>
</main>
💡 Skip Links and <main>
You know those "Skip to main content" links at the top of accessible websites? They jump the user directly to the <main> element, bypassing the header and navigation. This is one of the most impactful accessibility features you can add.
<footer>
Contains closing information — copyright notices, related links, contact details, or social media icons:
<footer>
<p>© 2026 Alex Johnson. All rights reserved.</p>
<nav>
<a href="privacy.html">Privacy Policy</a>
<a href="terms.html">Terms of Use</a>
</nav>
</footer>
Like <header>, a <footer> can appear inside an <article> or <section> too — not just at the bottom of the page.
Content Organization Elements
Inside your <main> content area, three semantic elements help organize the content itself:
<article>
Represents a self-contained, independently distributable piece of content. The test: could this content make sense on its own if you pulled it out of the page? If yes, it's an article.
<article>
<h2>How I Learned to Code</h2>
<p>Published on March 15, 2026</p>
<p>It all started when I discovered HTML...</p>
</article>
Common uses: blog posts, news articles, product cards, forum posts, user comments, social media posts.
<section>
Represents a thematic grouping of content, typically with its own heading. Unlike <article>, a section usually doesn't make sense on its own — it's part of a larger whole:
<section>
<h2>My Skills</h2>
<p>I'm learning HTML, CSS, and JavaScript.</p>
</section>
<section>
<h2>My Projects</h2>
<p>Here are some things I've built...</p>
</section>
Think of <section> as a chapter in a book. Each chapter has a title and groups related content, but a single chapter doesn't stand alone as a complete work.
<aside>
Contains content that is tangentially related to the surrounding content — something that enhances the main content but could be removed without losing the core message:
<aside>
<h3>Fun Fact</h3>
<p>The first website ever created is still online.
It was published in 1991 at CERN.</p>
</aside>
Common uses: sidebars, pull quotes, related links, "did you know" boxes, advertising, glossary definitions.
Self-contained content
(blog post, product card)"] A --> C["<section>
Thematic grouping
(chapter, tab panel)"] A --> D["<aside>
Tangentially related
(sidebar, fun fact)"] B --> E["Can contain
sections inside"] C --> F["Can contain
articles inside"] style A fill:#eff6ff,stroke:#3b82f6,stroke-width:2px,color:#1e293b style B fill:#f0fdf4,stroke:#22c55e,stroke-width:2px,color:#1e293b style C fill:#fdf4ff,stroke:#a855f7,stroke-width:2px,color:#1e293b style D fill:#fffbeb,stroke:#f59e0b,stroke-width:2px,color:#1e293b style E fill:#f8fafc,stroke:#64748b,stroke-width:1px,color:#1e293b style F fill:#f8fafc,stroke:#64748b,stroke-width:1px,color:#1e293b
💡 Article vs. Section — The Quick Test
Article: "Would this make sense in an RSS feed or shared independently?" → Use <article>.
Section: "Is this a thematic group within a larger page?" → Use <section>.
They can nest inside each other: an <article> can contain <section>s (like chapters of a blog post), and a <section> can contain <article>s (like a "Latest Posts" section with multiple post cards).
Figures and Captions
The <figure> element wraps self-contained content that is referenced from the main flow — typically an image, diagram, chart, or code example — along with an optional caption:
<figure>
<img src="images/sunset.jpg"
alt="A golden sunset over the Pacific Ocean">
<figcaption>Sunset at Venice Beach, March 2026.</figcaption>
</figure>
<figure>— wraps the content and its caption as a single unit<figcaption>— the visible caption (can go before or after the content inside the figure)
A <figure> isn't limited to images. You can use it for any referenced content:
<!-- A code example -->
<figure>
<pre><code>console.log("Hello, World!");</code></pre>
<figcaption>The classic first program in JavaScript.</figcaption>
</figure>
<!-- A quote -->
<figure>
<blockquote>
The best way to predict the future is to invent it.
</blockquote>
<figcaption>— Alan Kay</figcaption>
</figure>
💡 <figure> vs. Plain <img>
Not every image needs a <figure>. Use <figure> when an image (or other content) is referenced from the text as an illustration and benefits from a caption. Decorative images or inline photos that don't need captions can remain as plain <img> elements.
The Generic Containers: div and span
After learning all these semantic elements, where do <div> and <span> fit in?
<div> — Block-Level Container
A <div> is a generic block-level container with no semantic meaning. It starts on a new line and takes up the full available width:
<div class="card">
<h3>Featured Post</h3>
<p>Check out our latest article...</p>
</div>
<span> — Inline Container
A <span> is a generic inline container. It flows within text without breaking to a new line:
<p>My favorite color is <span class="highlight">blue</span>.</p>
When to Use Them
Use <div> and <span> only when no semantic element fits. They're styling hooks — containers for applying CSS — not content descriptors. If you can use <section>, <article>, <nav>, or another semantic element, always choose that first.
| Instead of... | Consider... |
|---|---|
<div class="header"> |
<header> |
<div class="navigation"> |
<nav> |
<div class="main-content"> |
<main> |
<div class="sidebar"> |
<aside> |
<div class="blog-post"> |
<article> |
<div class="footer"> |
<footer> |
Choosing the Right Element
With all these elements available, how do you decide which one to use? Here's a flowchart to help:
A complete page skeleton using all these elements together:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Blog</title>
</head>
<body>
<header>
<h1>My Blog</h1>
<nav>
<a href="index.html">Home</a>
<a href="about.html">About</a>
<a href="contact.html">Contact</a>
</nav>
</header>
<main>
<article>
<header>
<h2>My First Post</h2>
<p>Published April 10, 2026</p>
</header>
<section>
<h3>Getting Started</h3>
<p>I decided to learn web development...</p>
</section>
<section>
<h3>What I've Learned</h3>
<p>So far, I've covered HTML basics...</p>
</section>
<footer>
<p>Tags: HTML, Beginners, Web Dev</p>
</footer>
</article>
<aside>
<h2>About the Author</h2>
<p>Alex is a student learning to code.</p>
</aside>
</main>
<footer>
<p>© 2026 Alex Johnson</p>
</footer>
</body>
</html>
Hands-on Exercise
🏋️ Exercise: Refactor Your Homepage
Objective: Restructure your index.html using semantic elements.
Instructions:
- Open your
index.htmlfile in VS Code - Wrap the site title and navigation links in a
<header>with a<nav>inside it - Wrap the main page content (everything except header and footer) in a
<main> - Add an
<aside>inside<main>with a "Fun Fact" or "Did You Know" block - Wrap any image that has a caption in a
<figure>with<figcaption> - Add a
<footer>at the bottom with a copyright notice and links to your other pages - Make sure the heading hierarchy still makes sense (
<h1>→<h2>→<h3>) - Save and verify the page still looks the same in the browser
💡 Hint
Semantic elements don't change how the page looks by default — they're invisible to the eye. Your page should look exactly the same before and after this refactor. The changes are structural, not visual. You'll see the impact when you inspect the page with DevTools or test it with a screen reader.
✅ Example Solution
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My First Website</title>
</head>
<body>
<header>
<h1>Welcome to My Website</h1>
<nav>
<a href="index.html">Home</a> |
<a href="about.html">About</a> |
<a href="recipe.html">Recipes</a> |
<a href="contact.html">Contact</a>
</nav>
</header>
<main>
<section>
<h2>About This Site</h2>
<p>This is my first properly structured website.
I'm learning HTML and CSS from scratch!</p>
<figure>
<img src="images/sunset.jpg"
alt="A golden sunset over the ocean"
width="600" height="400">
<figcaption>A sunset photo from my collection.</figcaption>
</figure>
</section>
<section>
<h2>What I'm Learning</h2>
<ul>
<li>HTML structure and semantic elements</li>
<li>Links, images, and forms</li>
<li>How to connect pages together</li>
</ul>
</section>
<aside>
<h2>Fun Fact</h2>
<p>The first ever website is still live at
info.cern.ch. It was published in 1991!</p>
</aside>
</main>
<footer>
<p>© 2026 Alex Johnson. All rights reserved.</p>
<nav>
<a href="about.html">About</a> |
<a href="contact.html">Contact</a>
</nav>
</footer>
</body>
</html>
🎯 Quick Quiz
Question 1: How many <main> elements should a page have?
Question 2: What's the difference between <article> and <section>?
Question 3: When should you use <div>?
Question 4: What does the <aside> element represent?
Summary
🎉 Key Takeaways
- Semantic elements describe what content is; non-semantic elements (
<div>,<span>) are generic containers with no meaning <header>— introductory content;<nav>— major navigation;<main>— dominant unique content (one per page);<footer>— closing info<article>— self-contained content;<section>— thematic group;<aside>— tangentially related content<figure>and<figcaption>pair content with a visible caption- Use
<div>and<span>only when no semantic element fits — they're styling hooks, not content descriptors - Semantic HTML improves accessibility, SEO, and code readability at zero visual cost
📁 Your Project So Far
my-website/
├── images/
│ └── sunset.jpg
├── index.html ← refactored with semantic elements
├── about.html
├── recipe.html
└── contact.html
🎓 Module 2 Complete!
Congratulations — you've finished Module 2: HTML Essentials! You now know how to structure any web page using headings, text, links, images, lists, tables, forms, and semantic elements. That's the entire foundation of HTML.
🚀 What's Next?
Your pages have great structure but look plain — everything is in the browser's default styling with Times New Roman text and blue links. It's time to change that. In Module 3: CSS Essentials, you'll learn how to control colors, fonts, spacing, layout, and responsiveness. Your first CSS lesson will show you how to connect a stylesheet and transform your page's appearance with just a few lines of code.