🏗️ Semantic HTML
Semantic HTML means using HTML tags that clearly describe their content and purpose.
Instead of using generic <div> tags everywhere, we use meaningful tags like
<article>, <nav>, and <footer>.
Why Use Semantic HTML?
Screen readers can better understand and navigate your content, helping visually impaired users.
Search engines better understand your content structure, improving your search rankings.
Your code is easier to read and maintain. Other developers instantly know what each section does.
Finding and updating specific sections becomes much easier in large codebases.
Non-Semantic vs. Semantic
<!-- Uses generic div tags - no meaning -->
<div id="header">
<div id="nav">
<div><a href="/">Home</a></div>
<div><a href="/about">About</a></div>
</div>
</div>
<div id="main">
<div class="post">
<div class="title">Article Title</div>
<div class="content">Article content...</div>
</div>
</div>
<div id="footer">
<div>© 2024 My Website</div>
</div>
<!-- Uses meaningful HTML5 semantic tags -->
<header>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</header>
<main>
<article>
<h1>Article Title</h1>
<p>Article content...</p>
</article>
</main>
<footer>
<p>© 2024 My Website</p>
</footer>
Semantic HTML5 Elements
Page Structure Elements
| Tag | Purpose | Example Use |
|---|---|---|
<header> |
Introductory content or navigation | Site header with logo and menu |
<nav> |
Navigation links | Main menu, sidebar menu |
<main> |
Main content (unique to page) | Primary page content |
<article> |
Self-contained content | Blog post, news article, comment |
<section> |
Thematic grouping of content | Chapters, tabs, content blocks |
<aside> |
Tangentially related content | Sidebar, callout box, ads |
<footer> |
Footer content | Copyright, links, contact info |
Complete Page Structure Example
<!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>
<!-- Page header: logo, site title, main navigation -->
<header>
<h1>My Awesome 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 content: should be unique to each page -->
<main>
<!-- Blog post article -->
<article>
<header>
<!-- Articles can have their own headers -->
<h2>How to Learn Web Development</h2>
<p>Posted on <time datetime="2024-01-15">January 15, 2024</time></p>
</header>
<p>Learning web development is an exciting journey...</p>
<section>
<h3>Step 1: Learn HTML</h3>
<p>Start with the basics of HTML...</p>
</section>
<section>
<h3>Step 2: Learn CSS</h3>
<p>Once you know HTML, move to CSS...</p>
</section>
<footer>
<!-- Article footer: author, tags, share buttons -->
<p>Tags: <a href="/tag/tutorial">tutorial</a>, <a href="/tag/web-dev">web-dev</a></p>
</footer>
</article>
<!-- Sidebar with related content -->
<aside>
<h3>Related Articles</h3>
<ul>
<li><a href="/article1">CSS Basics</a></li>
<li><a href="/article2">JavaScript 101</a></li>
</ul>
</aside>
</main>
<!-- Page footer -->
<footer>
<p>© 2024 My Awesome Blog. All rights reserved.</p>
<nav>
<a href="/privacy">Privacy Policy</a> |
<a href="/terms">Terms of Service</a>
</nav>
</footer>
</body>
</html>
Content Semantic Elements
<article> vs <section>
These two are often confused. Here's the difference:
Use when: Content makes sense on its own and could be distributed independently.
Examples: Blog posts, news articles, forum posts, product cards, comments
Use when: Grouping related content that belongs together thematically.
Examples: Chapters in an article, tabbed content, different parts of a page
<!-- Article contains sections -->
<article>
<h2>Complete Guide to CSS</h2>
<section>
<h3>Introduction</h3>
<p>CSS stands for...</p>
</section>
<section>
<h3>Selectors</h3>
<p>CSS selectors let you...</p>
</section>
</article>
Text-Level Semantics
Use these tags to give meaning to inline text:
| Tag | Purpose | Example |
|---|---|---|
<strong> |
Strong importance | Warning: Do not enter |
<em> |
Emphasis | I really mean it |
<mark> |
Highlighted reference | Search results: keyword |
<time> |
Date/time | Posted on <time>2024-01-15</time> |
<code> |
Code snippet | Use the display property |
<abbr> |
Abbreviation | <abbr title="HyperText Markup Language">HTML</abbr> |
<p>
<strong>Important:</strong> The deadline is
<time datetime="2024-12-31">December 31, 2024</time>.
Please use the <code>submit()</code> function.
</p>
<p>
<abbr title="Cascading Style Sheets">CSS</abbr> is <em>essential</em>
for styling web pages.
</p>
Figures and Captions
Use <figure> and <figcaption> for images, diagrams,
code examples, or any content with a caption:
<!-- Image with caption -->
<figure>
<img src="chart.png" alt="Sales chart showing growth">
<figcaption>Figure 1: Sales growth from 2020-2024</figcaption>
</figure>
<!-- Code example with caption -->
<figure>
<pre><code>
function greet(name) {
return `Hello, ${name}!`;
}
</code></pre>
<figcaption>Example: Simple greeting function</figcaption>
</figure>
Accessibility Features
ARIA Landmarks (When Needed)
Modern semantic HTML usually provides sufficient accessibility. However, you can add ARIA roles for older browsers or screen readers:
<!-- Semantic HTML already has implicit roles -->
<header role="banner">...</header>
<nav role="navigation">...</nav>
<main role="main">...</main>
<footer role="contentinfo">...</footer>
Use semantic HTML first. Only add ARIA attributes when semantic HTML isn't sufficient. Remember: "No ARIA is better than bad ARIA."
Skip Navigation Links
Help keyboard users skip repetitive navigation and jump to main content:
<body>
<!-- Skip link (hidden visually, shown on keyboard focus) -->
<a href="#main-content" class="skip-link">Skip to main content</a>
<header>
<nav>...lots of links...</nav>
</header>
<main id="main-content">
<!-- Main content starts here -->
</main>
</body>
Common Mistakes to Avoid
<!-- BAD: Everything is a div -->
<div class="header">
<div class="nav">...</div>
</div>
<!-- GOOD: Use semantic tags -->
<header>
<nav>...</nav>
</header>
<!-- BAD: Multiple main tags -->
<main>...</main>
<main>...</main>
<!-- GOOD: Only one main per page -->
<main>...</main>
<!-- BAD: Using <strong> just to make text bold -->
<strong>This text needs to be bold</strong>
<!-- GOOD: Use CSS for styling -->
<span class="bold-text">This text needs to be bold</span>
Quick Reference: When to Use What
| Use Case | Tag |
|---|---|
| Main site header | <header> |
| Site navigation menu | <nav> |
| Primary page content | <main> |
| Blog post or news article | <article> |
| Related content group | <section> |
| Sidebar or callout | <aside> |
| Footer content | <footer> |
| No semantic meaning | <div> or <span> |
Summary
- Why semantic HTML matters (accessibility, SEO, readability)
- HTML5 semantic elements: header, nav, main, article, section, aside, footer
- The difference between article and section
- Text-level semantic tags: strong, em, mark, time, code
- How to use figure and figcaption
- Common mistakes to avoid