Lesson 2

Semantic HTML

Home › Courses › HTML › Lesson 2
🟠 Lesson 2 · 20 minutes

Semantic HTML.
Elements that mean something.

A div class="header" and a header tag look the same in a browser. But a screen reader, a search engine, and every developer reading your code treat them completely differently. Semantic HTML is the difference between a page that works and a page that works for everyone. This is the lesson that separates amateur HTML from professional HTML.

~20 minutes Beginner → Intermediate HTML5
HTML path ← Lesson 1 Why it matters 7 elements div vs section Full layout Challenge

Semantic HTML means using elements whose names describe their purpose: header for intro content, nav for navigation, main for primary content, article for self-contained pieces, section for thematic groupings, aside for tangents, footer for closing content. A div is a fallback when none of these fit. These 8 elements cover 90% of real page structure.

Before this lesson: complete Lesson 1. You need to be comfortable writing tags and opening files in a browser.

🎯 Why semantic HTML matters

Three reasons. All of them matter more than the extra typing costs.

1. Accessibility

Screen readers scan the page and announce landmarks: "navigation", "main content", "article". A page built with divs is announced as "generic container, generic container, generic container" — no structure. A page built with semantic elements is navigable. This is required for WCAG compliance and simple human decency.

2. SEO

Google's crawler reads HTML the same way a screen reader does. Semantic elements help Google identify what's navigation vs content vs promotional — which helps it rank the right elements. It also improves accessibility metrics Google tracks (Core Web Vitals, mobile experience).

3. Maintainability

Reading <nav class="sidebar-nav"> tells you exactly what it is. Reading <div class="sidebar"> requires opening the CSS file to figure out what it does. Six months from now, you are a stranger to your own code — semantic elements make you less of a stranger.

The trade is small: semantic elements are often one word longer than div. The gain is large: accessible structure, better SEO, and code that future-you can read. There is no downside to using them. There is a big downside to not using them.

🧱 The 7 elements you'll use constantly

Each one has a specific meaning. Learn what each is for, and the rest of HTML structure becomes obvious.

<header>

Introductory content for a page or section. Usually contains the logo, title, and sometimes navigation. Can appear at the top of the page OR inside an article — each article can have its own header.

<nav>

Navigation links. Primary site navigation, table of contents, previous/next links. Not every group of links is a nav — just the ones that are for navigating.

<main>

The primary content of the page — what the page is about. Exactly one per page. Excludes headers, footers, sidebars, and navigation. Screen readers let users jump directly to main.

<article>

Self-contained content that makes sense on its own. A blog post, a forum thread, a product review, a comment. If you could paste it into another page and it would still make sense, it's an article.

<section>

A thematic grouping of content, usually with a heading. Chapters within an article, tab panels, distinct page areas. Rule: if it doesn't have a natural heading, it's probably not a section — use a div.

<aside>

Content tangentially related to the main content. Sidebars, pull quotes, related links, ads, author bios. Content that could be removed without breaking the main flow.

<footer>

Closing content for a page or section. Copyright, contact links, related links, author info. Can appear at the bottom of the page OR at the end of an article.

<div>

The fallback. A generic container with no meaning. Use it when no semantic element fits — for pure styling groupings, layout wrappers, or structural anchors with no other semantic role.

Don't over-nest semantic elements. A section inside a section inside a section is confusing and rarely correct. If you're three levels deep, the middle one is probably a div. Semantic elements are for meaningful structure, not for grouping everything.

⚖️ div vs section — the rule

The most-asked semantic HTML question. The answer is clearer than it looks.

Use case Element Why
Has a heading, forms a thematic unitsectionDescribes a chapter-like grouping
Self-contained (blog post, review)articleWould make sense on its own
Page navigationnavDescribes navigation, not generic links
Page intro (logo, site title)headerDescribes the page's opening
Page main contentmainDescribes primary content, one per page
Sidebar, related contentasideDescribes tangential content
Footer (copyright, links)footerDescribes closing content
Pure layout wrapper, no meaningdivGeneric container for styling

The heading test. Ask: "does this grouping have a natural heading?" If yes, it's a section. If no, it's a div. That single question resolves 95% of div-vs-section decisions.

The paste test. Ask: "could I copy this into a different page and it would still make sense?" If yes, it's an article. If no, it's a section or div.

❌ Before: div soup

This is what non-semantic HTML looks like. It works visually, but it has no meaning.

bad.html
<div class="header">
<div class="logo">My Site</div>
<div class="nav">
<div class="nav-link"><a href="/">Home</a></div>
<div class="nav-link"><a href="/about">About</a></div>
</div>
</div>

<div class="main">
<div class="article">
<div class="article-title">My First Post</div>
<div class="article-body">
<p>Content here...</p>
</div>
</div>
</div>

<div class="sidebar">
<div class="sidebar-title">Related</div>
<div class="sidebar-link"><a href="/post-1">Post 1</a></div>
</div> cleavage

<div class="footer">
<div>&copy; 2026</div>
</div>

This page renders fine. A sighted user sees a normal website. But a screen reader sees: "generic container, generic container, link, link, generic container..." — with no indication of what's navigation, what's content, what's a sidebar. Google sees the same thing. Every semantic cue is missing.

✅ After: semantic HTML

Same visual result, same CSS. Completely different meaning.

good.html
<header>
<h1>My Site</h1>
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>

<main>
<article>
<h2>My First Post</h2>
<p>Content here...</p>
</article>
</main>

<aside>
<h3>Related</h3>
<ul>
<li><a href="/post-1">Post 1</a></li>
</ul>
</aside>

<footer>
<p>&copy; 2026</p>
</footer>

Screen readers

Now announce: "banner" (header), "navigation", "main", "article", "complementary" (aside), "contentinfo" (footer). Users can jump between landmarks instantly — like tabbing between sections in a Word document.

Search engines

Now know exactly which content is navigation (lower priority) vs main content (higher priority) vs sidebar (lower priority). The main content gets weighted accordingly.

Other developers

Now read the structure at a glance. "Oh, the header has nav, main has an article, there's a sidebar and footer" — all from the tags, no CSS needed.

🏗️ A real page structure

The layout that 90% of real websites follow. Learn it once, apply it everywhere.

layout.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Blog</title>
</head>
<body>

<header>
<h1>My Blog</h1>
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
</header>

<main>
<article>
<header>
<h2>Why I Love HTML</h2>
<p><time datetime="2026-10-24">October 24, 2026</time> by Alice</p>
</header>

<section>
<h3>The structure</h3>
<p>HTML gives structure to content...</p>
</section>

<section>
<h3>The accessibility</h3>
<p>Semantic elements help everyone...</p>
</section>

<footer>
<p>Thanks for reading!</p>
</footer>
</article>

<aside>
<h3>Related Posts</h3>
<ul>
<li><a href="/post-1">HTML Basics</a></li>
<li><a href="/post-2">CSS Introduction</a></li>
</ul>
</aside>
</main>

<footer>
<p>&copy; 2026 My Blog. All rights reserved.</p>
</footer>

</body>
</html>

Two headers

The page has a top-level header (site title + nav). The article has its own header (title + date). Both are correct — header can appear anywhere.

Two footers

The article has a footer (thanks for reading). The page has a footer (copyright). Both are correct — same rule as header.

One main

Only one main per page, containing the primary content. Screen readers let users jump directly to it, so multiple mains would be confusing.

Sections inside article

The article has two section elements, each with an h3. That's a thematic grouping inside a self-contained piece — exactly what section is for.

This is the layout every blog, docs site, and content site uses. Header, main (article + optional aside), footer. Once you have this pattern memorized, you can structure any page — a product page, a docs chapter, a portfolio. The elements change based on content, but the shape is the same.

🏆 Challenge

Two tasks. One fixes bad HTML. One builds good HTML.

Task 1 — Fix the div soup

Take the "bad.html" example from this lesson (the div soup version). Rewrite it using semantic elements. Keep all the text content the same. Change every div to the appropriate semantic element.

Compare your version to the "good.html" example. If they're similar, you've got it. If not, look at what's different.

Task 2 — Build a semantic page

Build a single-page site for a fictional product with this structure:

1. header — site title, nav with 3 links
2. main containing:
• an article about the product with 2 sections
• an aside with related products
3. footer — copyright + contact link

Use every element correctly. Add alt text to any images. Once you're done, open the page in your browser and in a screen reader (VoiceOver on Mac, NVDA on Windows). The screen reader should announce the structure — "banner", "navigation", "main", "article", etc.

⚠️ Common mistakes

The semantic HTML errors that catch every beginner.

1. Using div for everything

div class="header", div class="nav", div class="button" — this is div soup. If the class name describes a semantic element, use that element instead. Fix: header, nav, button.

2. Multiple main elements

One main per page — the primary content area. Multiple mains confuse screen readers. If you need multiple content areas, wrap them in article or section inside the single main.

3. Skipping heading levels for style

h1 → h4 to get a specific font size. Fix: use the correct heading level (h1 → h2 → h3) and change the size with CSS. Headings define document outline, not visual appearance.

4. section without a heading

A section is a thematic grouping — it should have a heading that identifies what the grouping is. If there's no natural heading, it's a div, not a section.

5. nav wrapping every group of links

Social links in the footer aren't "navigation" in the semantic sense. Related-posts links in an aside aren't nav either. Use nav only for actual navigation — primary site nav, breadcrumbs, table of contents, pagination.

6. header/footer inside nav

nav header — the header inside nav describes the nav, not the page. This is legal but often confusing. Keep header/footer at the page or article/section level, not inside nav.

7. article for every section

Not every content block is an article. An article is self-contained — could be syndicated to another site. A "Terms of Service" section inside a page isn't an article; it's a section of the page.

8. aside for anything

aside is for content tangentially related to the main content — a sidebar, a pull quote, related links. Using aside for the "contact form" on a contact page (that IS the main content) is wrong — the form should be in main.

➡️ What's next

You know how to structure a page. Next: the three elements that appear on every single one.

❓ Frequently asked questions

What is semantic HTML?

Semantic HTML means using elements that describe their meaning, not just their appearance. header instead of div class='header', nav instead of div class='nav', button instead of div onclick. The element name tells you and every other program what's inside.

What is the difference between div and section?

div is a generic container with no semantic meaning — a fallback. section is a thematic grouping of content, usually with a heading. If the content has a natural heading, it's a section. If it's just grouping for styling, it's a div.

What is the difference between article and section?

An article is self-contained — could be syndicated to another site (blog post, forum thread, review). A section is a thematic grouping within a larger context (chapter within an article, tabs within a page). Articles can contain sections.

Should I use header inside every section?

Yes — you can use header inside any section or article to group that section's heading and intro. A page usually has one main header at the top, but each article or section can have its own header with the article title.

Can I use multiple main elements?

No. Only one main element per page. It contains the primary content — what the page is fundamentally about. Screen readers let users jump directly to main, so having multiple is confusing.

Why does semantic HTML matter for SEO?

Google's crawler reads HTML the same way a screen reader does. Semantic elements help Google identify what's navigation vs content vs promotional. It also improves accessibility metrics Google tracks.

Do I need semantic HTML if I'm using CSS classes?

Yes. CSS classes only affect appearance — semantic elements affect meaning. A div class='header' looks the same as header to a browser, but screen readers and search engines read them differently. Both matter; they solve different problems.

How do I test if my HTML is semantic?

Two ways: (1) open the page in a screen reader (VoiceOver on Mac, NVDA on Windows) — you should hear landmarks announced. (2) Check the accessibility tree in Chrome DevTools → Elements → Accessibility. If you see "generic" repeated many times, you've got div soup.

🌐 External resources

← Back to HTML track
You're in the HTML track · Lesson 2