Semantic HTML
Write HTML that means something — use the right element for the right purpose for better accessibility and SEO.
1. Introduction
Semantic HTML means using HTML elements that communicate meaning — not just appearance. The word "semantic" means "relating to meaning".
Before HTML5, developers used <div> and <span> for everything. HTML5 introduced purpose-specific elements like <header>, <nav>, <main>, and <article>. These communicate the purpose of each section to browsers, search engines, and assistive technology.
2. Theory
Semantic vs Non-Semantic Elements
| Non-Semantic | Semantic Alternative | Meaning |
|---|---|---|
<div id="header"> | <header> | Page or section header |
<div id="nav"> | <nav> | Navigation links |
<div id="main"> | <main> | Main content of the page |
<div id="sidebar"> | <aside> | Sidebar / tangentially related content |
<div id="footer"> | <footer> | Page or section footer |
<div class="article"> | <article> | Self-contained content (blog post, news article) |
<div class="section"> | <section> | Themed grouping of content |
Page-Level Semantic Elements
<header>
<!-- Site logo, page title, navigation -->
</header>
<nav>
<!-- Primary navigation links -->
</nav>
<main>
<!-- The main unique content of the page -->
<!-- Only one <main> per page! -->
</main>
<aside>
<!-- Sidebar: related links, ads, author bio -->
</aside>
<footer>
<!-- Copyright, links, contact info -->
</footer>
Content Semantic Elements
<article>
<!-- A self-contained piece of content that makes sense on its own.
Blog posts, news articles, forum posts, product cards. -->
<header>
<h2>Article Title</h2>
<time datetime="2024-03-15">March 15, 2024</time>
</header>
<p>Article body...</p>
<footer>
<p>Written by <address>Jane Smith</address></p>
</footer>
</article>
<section>
<!-- A themed group of content -- needs a heading.
Use when content does not qualify as article or aside. -->
<h2>Our Services</h2>
<p>...</p>
</section>
Inline Semantic Elements
| Element | Meaning | Example |
|---|---|---|
<time> | A date or time | <time datetime="2024-12-25">Christmas Day</time> |
<address> | Contact information | <address>jane@example.com</address> |
<cite> | Citation/reference | <cite>The Great Gatsby</cite> |
<abbr> | Abbreviation | <abbr title="HyperText Markup Language">HTML</abbr> |
<code> | Computer code | <code>console.log()</code> |
<kbd> | Keyboard input | Press <kbd>Ctrl</kbd>+<kbd>S</kbd> |
<q> | Short inline quote | <q>To be or not to be</q> |
<blockquote> | Block-level quotation | For long quoted passages |
<mark> | Highlighted/relevant text | Search result highlighting |
When to Use <div> and <span>
Still use <div> and <span> when no semantic element fits — for layout wrappers, styling containers, or generic grouping. They have no inherent meaning, which is appropriate when meaning is not needed.
3. Real World Example
A news website uses: <header> for the masthead/logo, <nav> for the category menu, <main> for the articles area, multiple <article> elements for each story, <aside> for the "Trending" sidebar, and <footer> for links and copyright. This structure tells Google, screen readers, and browsers exactly what each section is — without reading a single word.
4. Code Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Blog</title>
</head>
<body>
<header>
<img src="logo.png" alt="Tech Blog Logo">
<h1>Tech Blog</h1>
<nav aria-label="Main navigation">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/articles">Articles</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>
<main>
<section aria-labelledby="featured-heading">
<h2 id="featured-heading">Featured Articles</h2>
<article>
<header>
<h3>Getting Started with CSS Grid</h3>
<p>By <address><a href="/authors/jane">Jane Smith</a></address>
on <time datetime="2024-03-15">15 March 2024</time></p>
</header>
<p>CSS Grid is a powerful layout system that allows you to create
two-dimensional layouts with ease...</p>
<a href="/articles/css-grid">Read more</a>
</article>
<article>
<header>
<h3>JavaScript ES6 Features You Should Know</h3>
<p>By <address><a href="/authors/bob">Bob Jones</a></address>
on <time datetime="2024-03-10">10 March 2024</time></p>
</header>
<p>ES6 introduced many improvements to JavaScript. Here are the
features every developer should be using...</p>
<a href="/articles/es6-features">Read more</a>
</article>
</section>
</main>
<aside aria-label="Trending topics">
<h2>Trending</h2>
<ul>
<li><a href="/tag/javascript">JavaScript</a></li>
<li><a href="/tag/css">CSS</a></li>
<li><a href="/tag/react">React</a></li>
</ul>
</aside>
<footer>
<p>© 2024 Tech Blog. All rights reserved.</p>
<nav aria-label="Footer navigation">
<a href="/privacy">Privacy Policy</a> |
<a href="/terms">Terms of Service</a> |
<a href="/contact">Contact</a>
</nav>
</footer>
</body>
</html>
5. Code Breakdown
| Element | Purpose in this example |
|---|---|
<header> | The site masthead — contains logo, site title, and main nav |
<nav aria-label="Main navigation"> | Primary navigation. aria-label distinguishes it from the footer nav for screen readers |
<main> | The page's unique main content — only one per page |
<section aria-labelledby="..."> | A section labelled by its heading. aria-labelledby connects the section to its <h2> |
<article> | Each blog post is self-contained — could be syndicated or shared independently |
<address> | Contact info for the article author |
<time datetime="2024-03-15"> | Human-readable date with machine-readable format for search engines and calendars |
<aside> | Sidebar with related but not essential content |
<footer> | Site footer with copyright and secondary navigation |
6. Common Mistakes
Writing <div class="header"> instead of <header> does the same visual job but loses all semantic meaning. Screen readers and search engines cannot tell it is a header.
A page should have exactly one <main> element. It represents the main content unique to that page. Having two <main> elements is invalid HTML.
Every <section> should have a heading (h2–h6) that describes it. A section without a heading is usually better represented as a <div>.
<article> is self-contained — it should make sense if extracted from the page. <section> is a themed grouping within a page, not independently meaningful.
7. Best Practices
8. Practice Exercise
Take your About Me page and refactor it using semantic HTML. Replace all <div> elements with appropriate semantic elements:
- Wrap the page title and navigation in
<header> - Put navigation links in
<nav> - Wrap the main content in
<main> - Create 2–3
<section>elements for different parts (bio, skills, hobbies) - Add a
<footer>with contact info in<address>
9. Assignment
Build a blog homepage with semantic HTML. It must include: a <header> with the blog name and <nav>, a <main> containing a <section> with at least 3 <article> elements (each with its own <header>, author <address>, and <time>), an <aside> with categories or recent posts, and a <footer> with copyright and links.
10. Interview Questions
Q1: What is semantic HTML and why does it matter?
Answer: Semantic HTML uses elements that communicate the meaning and purpose of content, not just its appearance. It matters for three reasons: 1) Accessibility — screen readers use semantic elements to help visually impaired users navigate pages. 2) SEO — search engines use semantic structure to understand page content and rank it appropriately. 3) Maintainability — semantic code is easier for developers to understand.
Q2: What is the difference between <article> and <section>?
Answer: <article> represents self-contained content that could be independently distributed or syndicated — a blog post, news article, comment, product card. <section> is a thematic grouping of content within a page — it requires a heading and represents a chunk of a page, not an independently meaningful unit.
Q3: What is the purpose of the <main> element?
Answer: <main> contains the dominant, unique content of a page — the content that differs from page to page. There should be exactly one <main> per page. Screen reader users often jump directly to <main> to skip navigation and headers.
Q4: What is the <time> element for?
Answer: <time> represents a date or time in a human-readable format while providing a machine-readable format via the datetime attribute. For example: <time datetime="2024-03-15">March 15, 2024</time>. Search engines and calendar applications use the datetime value to accurately parse dates regardless of the display format.