—HTML Series · Post 08: Semantic HTML

Post 8 — Semantic HTML | CodeHerWay
Post 08

🏗️ Semantic HTML (Extremely Important)

This is the single most important concept in this entire course. Semantic HTML is what separates someone who writes HTML from someone who writes it well. This is what makes you professional.

⚡ CORE CONCEPT — This Changes Everything
<header> <nav> <main> <section> <article> <aside> <footer> accessibility SEO

The Difference Between Writing HTML and Writing It Well

You can build an entire website using nothing but <div> tags. You can wrap every section in a <div>, every header in a <div>, every navigation menu in a <div>. It will render in the browser. It will look correct. And it will be completely wrong.

A <div> is a generic container. It means nothing. It tells the browser "here's a box," but it says nothing about what's inside that box. A screen reader hitting a wall of <div> elements is like a person walking into a building with no signs on any door — every room looks the same, and there's no way to find anything without opening every single one.

Semantic HTML solves this. Instead of generic <div> containers, you use elements that describe what the content is. A <nav> tells the browser "this is navigation." A <header> says "this is the header." A <main> says "this is the main content." The page looks the same visually, but underneath, it's organized, meaningful, and accessible.

🧠 Mindset Shift

Think of semantic HTML as the difference between a building with labeled rooms and a building where every door is blank. Both buildings are functional. But only one is usable by everyone — especially people who can't see the interior. When you write semantic HTML, you're building the labels, the signs, the wayfinding system. You're building a building that works for humans, not just browsers.

Why This Matters More Than You Think

Accessibility
Screen readers use semantic elements to navigate. Proper structure means your site works for everyone.
🔍
SEO
Google's crawlers understand semantic elements. They know what's navigation, what's content, what's a sidebar.
📱
Screen Readers
Users can jump directly to <nav>, <main>, or <footer> using landmark navigation. No semantic = no landmarks.
🧹
Clean Structure
Semantic code is self-documenting. Another developer reads <header> and instantly knows what it is.
JavaScript Targeting
Selecting document.querySelector('main') is clearer and safer than targeting a div with a random class.

This isn't theoretical. It's practical. Hiring managers look at your HTML source. Accessibility audits flag non-semantic markup. Google's Lighthouse tool measures it. And over one billion people worldwide use assistive technology. Semantic HTML isn't a nice-to-have — it's a professional requirement.

The <div> Soup Problem

Let's see the problem in action. Here's a page structure using nothing but <div> elements, vs. the same structure with semantic HTML:

❌ Div Soup
<div class="header"> <div class="nav"> <div class="nav-links">...</div> </div> </div> <div class="main"> <div class="content"> <div class="post">...</div> </div> <div class="sidebar">...</div> </div> <div class="footer">...</div>
✅ Semantic HTML
<header> <nav> <ul>...</ul> </nav> </header> <main> <section> <article>...</article> </section> <aside>...</aside> </main> <footer>...</footer>

They render identically in the browser. But the left version is a pile of meaningless boxes. The right version is a labeled blueprint. A screen reader can jump from the nav to the main content to the footer. Google can identify your primary content vs. sidebar content. A new developer joining your project can scan the HTML and understand the page structure in seconds.

The Semantic Page Blueprint

Here's how semantic elements map to a typical page layout. This is the structure of virtually every professional website:

<header>
<nav>
<main>
<section>
<article>
<article>
<aside>
↑ Typical semantic page structure

The Seven Semantic Elements You Need to Know

<header> Introductory content
The introductory section of the page or a section within the page. Typically contains the site logo, site title, and navigation. A page can have multiple <header> elements — one for the page, and one inside each <article> or <section> if needed.
✅ Use for: site header, article header, section header
❌ Don't use for: random wrapper divs, footer content
HTML
<header> <h1>CodeHerWay</h1> <p>Where women code, lead, and rewrite the future of tech.</p> </header>
<nav> Navigation
Wraps a set of navigation links. Screen readers announce this as a navigation landmark, allowing users to jump directly to it. Use it for primary site navigation, secondary menus, or breadcrumb trails. Don't use it for every group of links — only groups that represent major navigation.
✅ Use for: main nav, secondary nav, breadcrumbs, table of contents
❌ Don't use for: a random list of links in a paragraph, footer social links
HTML
<nav> <ul> <li><a href="#about">About</a></li> <li><a href="#projects">Projects</a></li> <li><a href="#contact">Contact</a></li> </ul> </nav>
<main> Primary content
The primary content of the page — the stuff that's unique to this specific page. There should be only one <main> per page. It excludes content that repeats across pages (header, nav, footer). Screen readers use it as the main content landmark.
✅ Use for: the unique content area of every page
❌ Don't use for: multiple times on one page, inside <header> or <footer>
💡 Pro Tip

The <main> element is the most powerful landmark for accessibility. When a screen reader user presses a shortcut key to "jump to main content," they land inside <main>. Without it, they have to tab through your entire header and navigation on every single page load. One element. Massive impact.

<section> Thematic group
A thematic grouping of content, usually with its own heading. Think of it as a chapter in a book. Use <section> when a chunk of content forms a cohesive unit with a distinct topic — your "About" section, your "Projects" section, your "Testimonials" section.
✅ Use for: distinct content sections with their own headings
❌ Don't use for: generic wrappers (use <div> for that), styling hooks
<article> Self-contained content
A piece of self-contained content that could stand on its own — a blog post, a product card, a news story, a comment. The test: if you extracted this content and put it on a completely different page or in an RSS feed, would it still make sense? If yes, it's an <article>.
✅ Use for: blog posts, product cards, news stories, user comments, forum posts
❌ Don't use for: generic page sections, wrappers for layout
ℹ️ Good to Know

<section> and <article> are the pair that confuses everyone. Here's the simple rule: articles can live inside sections, and sections can live inside articles. A "Blog" section might contain multiple article elements. A single long article might be divided into sections. They're not mutually exclusive — they're complementary.

<aside> Tangential content
Content that is tangentially related to the main content — a sidebar, a pull quote, an ad, related links, or supplementary information. It's not essential to the main content but provides additional context. Screen readers identify it as a complementary landmark.
✅ Use for: sidebars, pull quotes, related links, ads, author bios
❌ Don't use for: primary content, main navigation
<footer> Closing content
The closing section of the page or a section. Typically contains copyright info, contact links, social media links, and legal text. Like <header>, a page can have multiple <footer> elements — one for the page, and one inside articles or sections.
✅ Use for: site footer, article footer, copyright info
❌ Don't use for: header content, navigation-heavy sections

The Complete Semantic Template

Here's what a fully semantic portfolio page looks like. This is the template you should base every project on:

HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Jenna Torres — Frontend Developer</title> </head> <body> <header> <h1>Jenna Torres</h1> <nav> <ul> <li><a href="#about">About</a></li> <li><a href="#projects">Projects</a></li> <li><a href="#contact">Contact</a></li> </ul> </nav> </header> <main> <section id="about"> <h2>About Me</h2> <p>Frontend developer who builds fast, accessible websites.</p> </section> <section id="projects"> <h2>Projects</h2> <article> <h3>Weather Dashboard</h3> <p>Real-time weather app using API data.</p> </article> <article> <h3>LUXE E-Commerce</h3> <p>Product page with interactive shopping cart.</p> </article> </section> <section id="contact"> <h2>Contact</h2> <p><a href="mailto:[email protected]">Email me</a></p> </section> </main> <aside> <h2>Currently Learning</h2> <p>React, TypeScript, and accessibility best practices.</p> </aside> <footer> <p>&copy; 2025 Jenna Torres. Built with love and semantic HTML.</p> </footer> </body> </html>

What a Screen Reader Actually Hears

This is what makes semantic HTML real instead of theoretical. Here's an approximation of what a screen reader announces when it encounters the semantic page above vs. the div-soup version:

Screen Reader — Semantic HTML
Banner landmark. Heading level 1: "Jenna Torres"
Navigation landmark. List, 3 items.
Link: "About" — Link: "Projects" — Link: "Contact"
Main landmark.
Region: Heading level 2: "About Me"
Region: Heading level 2: "Projects"
Article: Heading level 3: "Weather Dashboard"
Article: Heading level 3: "LUXE E-Commerce"
Complementary landmark. Heading level 2: "Currently Learning"
Content info landmark. "© 2025 Jenna Torres."
Screen Reader — Div Soup
Group. Heading level 1: "Jenna Torres"
Group. List, 3 items.
Link: "About" — Link: "Projects" — Link: "Contact"
Group.
Group. Heading level 2: "About Me"
Group. Heading level 2: "Projects"
Group. Heading level 3: "Weather Dashboard"
Group. Heading level 3: "LUXE E-Commerce"
Group. Heading level 2: "Currently Learning"
Group. "© 2025 Jenna Torres."

See the difference? The semantic version gives the user a map of the page. They can jump directly to the navigation, skip to main content, or find the footer — all without scrolling through everything. The div-soup version? Every section is just "Group." No landmarks. No shortcuts. No structure. The user has to read the entire page linearly to find anything.

🧠 Mindset Shift

Accessibility isn't a charity feature you add if you have extra time. It's a quality standard. The same way you wouldn't ship a site with broken links, you shouldn't ship a site with broken semantics. Every <div> you use where a semantic element would work is a door with no label, a room with no sign. Your users — all of them — deserve better.

When <div> Is Still the Right Choice

After all of this, you might think <div> is evil. It's not. <div> still has a legitimate purpose: it's a generic container for layout and styling when no semantic element fits.

Need to wrap some elements to apply a CSS grid or flexbox layout? Use a <div>. Need a wrapper for a background color that doesn't represent a meaningful section? Use a <div>. Need a container for JavaScript to target that doesn't have semantic meaning? Use a <div>.

The rule is simple: if a semantic element fits, use it. If none fits, use <div>. The problem was never <div> existing — it was <div> being used for everything.

💡 Pro Tip

A quick mental checklist before writing any container element: Is this a header? Use <header>. Navigation? <nav>. The main content? <main>. A thematic section with its own heading? <section>. Self-contained content? <article>. Supplementary info? <aside>. Closing section? <footer>. None of the above? Now use <div>.

🔥 Dev_Fession

My first three portfolio projects were built entirely with <div> elements. Not some divs — all divs. <div class="header">, <div class="nav">, <div class="main">, <div class="footer">. I named them semantically in my classes but used the most meaningless element possible for every single one.

I applied to a junior developer role and the hiring manager pulled up my portfolio's source code during the interview. She said, "I see you're using class names like 'header' and 'nav' — are you aware that HTML has actual elements for those?"

I wasn't. I genuinely did not know that <header>, <nav>, <main>, and <footer> existed as real HTML elements. I'd only ever seen <div> in the tutorials I followed, so I assumed that's how you built everything.

I didn't get that job. But I went home, read the MDN docs on semantic HTML, and refactored every project I had. The HTML got shorter. The code got cleaner. And I never used a <div> where a semantic element belonged again. That interview rejection was the most valuable feedback I've ever received.

🏆 Mini Build: Semantic Portfolio Structure

Rebuild your portfolio page using zero unnecessary <div> elements. Every container must be a semantic element. Here's your checklist:

1
Wrap your logo and navigation in a <header>. Put the nav links in a <nav> with a <ul>.
2
Wrap all unique page content in a single <main>. Only one per page.
3
Create at least three <section> blocks inside <main>: About, Projects, and Contact. Each must have its own <h2>.
4
Inside the Projects section, create at least two <article> elements — one per project. Each article gets an <h3>, a paragraph, and a link.
5
Add an <aside> somewhere on the page — a "Currently Learning" sidebar, a fun fact, or a favorite quote.
6
Close the page with a <footer> containing your copyright, social links, and tagline.
7
Bonus: Right-click your finished page, select "View Page Source," and count your <div> elements. Your goal: fewer than three. Ideally zero.

Recap

Semantic HTML means using elements that describe what the content is, not just how it looks. <header> for introductory content. <nav> for navigation. <main> for the primary content (one per page). <section> for thematic groups. <article> for self-contained content. <aside> for supplementary content. <footer> for closing content. Use <div> only when no semantic element fits.

This isn't optional knowledge. It's the line between beginner HTML and professional HTML. It impacts accessibility, SEO, code readability, and how seriously other developers take your work. Every page you build from this point forward should be semantic by default.

Previous
Previous

—HTML Series · Post 9: Container Showdown: <div> vs <span>

Next
Next

—HTML Series · Post 07: HTML Lists