Semantic HTML is one of the most important concepts in modern, professional HTML.
So far, we've learned how to create:
Now we're going to learn how to give the page's content meaning and structure.
The word semantic means:
Something that has meaning.
Semantic HTML uses HTML elements that describe what the content represents, rather than simply describing how it should look.
For example:
<div>
Navigation
</div>works technically, but doesn't tell the browser what that content actually is.
Instead:
<nav>
Navigation
</nav>communicates:
"This is navigation."
<div class="header">
...
</div>
<div class="navigation">
...
</div>
<div class="content">
...
</div>
<div class="footer">
...
</div>The browser sees several generic containers.
<header>
...
</header>
<nav>
...
</nav>
<main>
...
</main>
<footer>
...
</footer>Now the structure communicates meaning.
Semantic HTML provides several benefits.
Assistive technologies can understand the page structure better.
Search engines can better understand the roles and relationships of content.
Developers can understand the code more easily.
A page has a predictable structure.
The browser understands what different regions represent.
Think:
Semantic HTML
│
├── Accessibility
├── SEO
├── Maintainability
└── Clear structureThe most important page-level semantic elements are:
<header>
<nav>
<main>
<section>
<article>
<aside>
<footer>A typical page might look like:
┌──────────────────────────────────────┐
│ HEADER │
│ Logo + Website Title │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│ NAV │
│ Home | About | Blog | Contact │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│ │
│ MAIN │
│ │
│ ┌──────────────────────────────┐ │
│ │ ARTICLE │ │
│ │ │ │
│ │ Blog Post │ │
│ └──────────────────────────────┘ │
│ │
│ ┌──────────────┐ │
│ │ ASIDE │ │
│ │ Related Posts│ │
│ └──────────────┘ │
│ │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│ FOOTER │
└──────────────────────────────────────┘Let's understand each element.
<header>#<header> represents introductory content for a page or section.
Example:
<header>
<h1>NextGen Blog</h1>
<p>Latest technology and AI news</p>
</header>A header can contain:
This is a common misconception.
<header> can belong to the entire page:
<body>
<header>
<h1>My Blog</h1>
</header>
</body>But it can also belong to an article:
<article>
<header>
<h2>Understanding Kubernetes</h2>
<p>Published on October 1, 2026</p>
</header>
...
</article>So:
<header>
↓
introductory contentnot necessarily:
<header>
↓
website top bar only<nav>#<nav> represents a section containing navigation links.
Example:
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/blog">Blog</a>
<a href="/contact">Contact</a>
</nav>A more structured version:
<nav aria-label="Main navigation">
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/about">About</a>
</li>
<li>
<a href="/blog">Blog</a>
</li>
<li>
<a href="/contact">Contact</a>
</li>
</ul>
</nav><nav>?#No.
This is an important semantic distinction.
Suppose you have:
<p>
Read our
<a href="/privacy">Privacy Policy</a>.
</p>That doesn't necessarily need:
<nav><nav> is intended for major navigation blocks.
Examples:
Main navigation
Table of contents
Pagination navigation
Previous/next article navigationNot every individual link.
<nav> Elements#A page can contain multiple navigation sections.
For example:
<nav aria-label="Main navigation">
...
</nav>
<nav aria-label="Table of contents">
...
</nav>
<nav aria-label="Pagination">
...
</nav>The aria-label helps distinguish their purposes when there are multiple navigation landmarks.
<main>#<main> represents the dominant content of the document.
Example:
<main>
<h1>HTML Tutorial</h1>
<p>
Learn HTML from beginner to advanced.
</p>
</main>Think:
<header>
Site introduction
</header>
<nav>
Navigation
</nav>
<main>
Primary content
</main>
<footer>
Footer information
</footer><main> Should Represent the Main Content#Suppose you're on a blog article:
Header
Navigation
Sidebar
Blog article
FooterThe blog article is likely the primary content.
So:
<main>
<article>
...
</article>
</main>A document generally has one main content region.
Typical structure:
<body>
<header>
...
</header>
<nav>
...
</nav>
<main>
...
</main>
<footer>
...
</footer>
</body>Don't use <main> repeatedly simply as a generic container.
<section>#<section> represents a thematic grouping of content.
Example:
<section>
<h2>Our Services</h2>
<p>
We provide web development services.
</p>
</section>Think:
<section>
= a meaningful topic/groupA good section generally has a heading.
Example:
<section>
<h2>Latest Articles</h2>
...
</section>Another:
<section>
<h2>Customer Reviews</h2>
...
</section>Another:
<section>
<h2>Pricing</h2>
...
</section>This makes the document structure easier to understand.
<section> Is Not Just a Styled <div>#This is a common mistake.
Bad:
<section>
<div>Red box</div>
</section>
<section>
<div>Blue box</div>
</section>If the sections don't represent meaningful thematic groups, <section> may not be appropriate.
Sometimes:
<div>is actually the correct element.
Remember:
<div>
→ generic container
<section>
→ meaningful thematic grouping<article>#<article> represents self-contained content that could potentially stand on its own.
Examples:
Example:
<article>
<h2>What Is Kubernetes?</h2>
<p>
Kubernetes is a container orchestration platform...
</p>
</article>A blog page might contain:
<main>
<h1>Latest Articles</h1>
<article>
<h2>Introduction to AI Agents</h2>
<p>...</p>
</article>
<article>
<h2>Understanding Kubernetes</h2>
<p>...</p>
</article>
<article>
<h2>What Is RAG?</h2>
<p>...</p>
</article>
</main>Each article represents an independent piece of content.
<article> Can Contain <header> and <footer>#Example:
<article>
<header>
<h2>Understanding RAG</h2>
<p>
Published October 1, 2026
</p>
</header>
<p>
Retrieval-Augmented Generation combines
retrieval with language models.
</p>
<footer>
<p>
Author: Anubhav
</p>
</footer>
</article>This is a perfectly valid semantic structure.
<aside>#<aside> represents content that is indirectly related to the main content.
Examples:
Example:
<aside>
<h2>Related Articles</h2>
<ul>
<li>
<a href="/html">Learn HTML</a>
</li>
<li>
<a href="/css">Learn CSS</a>
</li>
</ul>
</aside><aside> Doesn't Always Mean Sidebar#Another common misconception:
aside = sidebarNot necessarily.
For example:
<article>
<h1>HTML Forms</h1>
<p>...</p>
<aside>
<p>
Tip: Always associate labels with controls.
</p>
</aside>
<p>...</p>
</article>Here the <aside> is related to the article but not part of its primary flow.
<footer>#<footer> represents footer information for a page or section.
Example:
<footer>
<p>
© 2026 NextGen Blog
</p>
</footer>But just like <header>, <footer> isn't restricted to the entire webpage.
An article can have a footer:
<article>
<h2>HTML Semantic Elements</h2>
<p>...</p>
<footer>
<p>Author: Anubhav</p>
</footer>
</article>Let's combine everything.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
>
<title>NextGen Blog</title>
</head>
<body>
<header>
<h1>NextGen Blog</h1>
<p>
Technology, AI and software development
</p>
</header>
<nav aria-label="Main navigation">
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/ai">AI</a>
</li>
<li>
<a href="/programming">Programming</a>
</li>
<li>
<a href="/about">About</a>
</li>
</ul>
</nav>
<main>
<section>
<h2>Latest Articles</h2>
<article>
<header>
<h3>
Understanding AI Agents
</h3>
<p>
Published October 1, 2026
</p>
</header>
<p>
AI agents can perform tasks rather than
simply answering questions.
</p>
<footer>
<p>
Author: Anubhav
</p>
</footer>
</article>
<article>
<header>
<h3>
Introduction to Kubernetes
</h3>
<p>
Published October 1, 2026
</p>
</header>
<p>
Kubernetes helps manage containerized
applications at scale.
</p>
<footer>
<p>
Author: Anubhav
</p>
</footer>
</article>
</section>
<aside>
<h2>Popular Articles</h2>
<ul>
<li>
<a href="/html">
Complete HTML Guide
</a>
</li>
<li>
<a href="/rag">
Understanding RAG
</a>
</li>
</ul>
</aside>
</main>
<footer>
<p>
© 2026 NextGen Blog
</p>
<nav aria-label="Footer navigation">
<a href="/privacy">
Privacy
</a>
<a href="/terms">
Terms
</a>
</nav>
</footer>
</body>
</html>The browser can conceptually represent that page as:
html
│
├── head
│
└── body
│
├── header
│ ├── h1
│ └── p
│
├── nav
│ └── ul
│ ├── li
│ ├── li
│ ├── li
│ └── li
│
├── main
│ │
│ ├── section
│ │ │
│ │ ├── h2
│ │ │
│ │ ├── article
│ │ │ ├── header
│ │ │ ├── p
│ │ │ └── footer
│ │ │
│ │ └── article
│ │
│ └── aside
│
└── footer
└── navThis is much easier to understand than:
div
├── div
├── div
├── div
│ ├── div
│ └── div
└── divSemantic HTML creates useful landmarks.
Common landmarks include:
<header>
<nav>
<main>
<aside>
<footer>Assistive technologies can use these structural regions to help users navigate the page.
For example, a screen-reader user can understand:
Navigation
Main content
Complementary content
Footerwithout having to read every element sequentially.
<div> vs Semantic Elements#This is one of the most important HTML interview topics.
<div>#Use when you need a generic container and no more meaningful semantic element applies.
<div class="card">
...
</div><section>#Use when the content forms a meaningful thematic section.
<section>
<h2>Our Services</h2>
...
</section><article>#Use when the content is independently distributable/self-contained.
<article>
<h2>How RAG Works</h2>
...
</article><aside>#Use for tangential/supporting content.
<aside>
Related Articles
</aside>When deciding what element to use:
What is this content?
│
├── Independent content?
│ ↓
│ <article>
│
├── Thematic section?
│ ↓
│ <section>
│
├── Supporting/tangential content?
│ ↓
│ <aside>
│
├── Navigation?
│ ↓
│ <nav>
│
└── No meaningful semantic role?
↓
<div>This is a very useful mental model.
<section> vs <article>#This confuses many beginners.
Consider a blog homepage:
Latest Articles
Article 1
Article 2
Article 3A reasonable structure:
<section>
<h2>Latest Articles</h2>
<article>
Article 1
</article>
<article>
Article 2
</article>
<article>
Article 3
</article>
</section>Think:
section
↓
group of related content
article
↓
individual self-contained contentAbsolutely.
Example:
<article>
<h1>Understanding Kubernetes</h1>
<section>
<h2>What Is Kubernetes?</h2>
<p>...</p>
</section>
<section>
<h2>Why Use Kubernetes?</h2>
<p>...</p>
</section>
<section>
<h2>How Kubernetes Works</h2>
<p>...</p>
</section>
</article>This gives a strong semantic hierarchy.
Yes.
<section>
<h2>Latest News</h2>
<article>
News article 1
</article>
<article>
News article 2
</article>
</section>Very common for:
<figure> and <figcaption>#We encountered these in the Images chapter.
They're also semantic elements.
Example:
<figure>
<img
src="kubernetes.png"
alt="Kubernetes architecture diagram"
>
<figcaption>
Basic Kubernetes architecture
</figcaption>
</figure><figure> represents self-contained content such as:
And:
<figcaption>provides its caption.
<address>#<address> represents contact information for the relevant page or article author/owner.
Example:
<address>
Contact:
<a href="mailto:hello@example.com">
hello@example.com
</a>
</address>For an article:
<article>
<h1>Understanding HTML</h1>
<address>
By Anubhav Chaudhary
</address>
...
</article>Important:
<address> is not simply a generic element for displaying any postal address.
Its semantic purpose is contact information.
<time>#<time> represents dates, times, or durations.
Example:
<time datetime="2026-10-01">
October 1, 2026
</time>The human-readable text is:
October 1, 2026while:
datetime="2026-10-01"provides machine-readable information.
Consider:
<time datetime="2026-10-01">
October 1, 2026
</time>Humans see:
October 1, 2026Machines can interpret:
2026-10-01This is useful for:
Semantic HTML can help search engines understand content structure.
Compare:
<div class="title">
Best AI Tools
</div>with:
<h1>
Best AI Tools
</h1>The second explicitly communicates:
This is the page's primary heading.
Similarly:
<article>communicates that content represents an article.
Semantic HTML doesn't magically guarantee higher rankings, but it provides clearer machine-readable structure.
Semantic HTML doesn't mean you cannot style it.
For example:
<header class="site-header">can still have CSS.
.site-header {
padding: 20px;
}Semantic meaning and visual design are separate concepts.
Think:
HTML
↓
Meaning + Structure
CSS
↓
Presentation
JavaScript
↓
BehaviorJavaScript can work with semantic elements just like other DOM elements.
Example:
const nav = document.querySelector("nav");or:
const articles = document.querySelectorAll("article");Semantic HTML therefore doesn't restrict JavaScript.
It improves the structure that JavaScript interacts with.
Consider:
<div class="header">
<div class="logo">
My Website
</div>
<div class="navigation">
<div>Home</div>
<div>About</div>
</div>
</div>
<div class="main">
<div class="article">
...
</div>
</div>
<div class="footer">
...
</div>Problems:
<header>
<a href="/">
My Website
</a>
<nav aria-label="Main navigation">
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/about">About</a>
</li>
</ul>
</nav>
</header>
<main>
<article>
<h1>My Article</h1>
<p>
Article content...
</p>
</article>
</main>
<footer>
<p>
© 2026 My Website
</p>
</footer>Much clearer.
This is extremely important.
You should not try to replace every <div> with a semantic element.
If no meaningful semantic element exists:
<div>is perfectly valid.
For example, a purely visual wrapper:
<div class="card-grid">
...
</div>may appropriately remain a <div>.
The goal isn't:
Use zero divs.The goal is:
Use the most appropriate semantic element when one exists.A modern page often looks like:
<body>
<header>
Site header
</header>
<nav>
Main navigation
</nav>
<main>
<section>
Main topic
</section>
<section>
Another topic
</section>
<aside>
Supporting content
</aside>
</main>
<footer>
Site footer
</footer>
</body>But remember:
There is no single mandatory layout.
The correct semantic structure depends on the actual content.
Imagine an online store.
<header>
<h1>NextGen Store</h1>
<nav aria-label="Main navigation">
...
</nav>
</header>
<main>
<section>
<h2>Featured Products</h2>
<article>
<h3>Wireless Headphones</h3>
<p>₹4,999</p>
<a href="/products/headphones">
View Product
</a>
</article>
<article>
<h3>Smart Watch</h3>
<p>₹8,999</p>
<a href="/products/watch">
View Product
</a>
</article>
</section>
</main>
<footer>
...
</footer>Each product can be represented as an <article> if it is treated as a self-contained item.
<header>
<h1>NextGen Blog</h1>
</header>
<nav aria-label="Main navigation">
...
</nav>
<main>
<article>
<header>
<h1>What Are AI Agents?</h1>
<p>
Published:
<time datetime="2026-10-01">
October 1, 2026
</time>
</p>
</header>
<section>
<h2>Introduction</h2>
<p>...</p>
</section>
<section>
<h2>How AI Agents Work</h2>
<p>...</p>
</section>
<footer>
<address>
Author: Anubhav
</address>
</footer>
</article>
<aside>
<h2>Related Articles</h2>
...
</aside>
</main>
<footer>
...
</footer>This is a very strong semantic structure.
When building a page, ask:
Do I have a header?
Do I have navigation?
Do I have a main content region?
Do I need an aside?
Do I have a footer?Is this a section?
Is this an article?
Is this just a generic container?Are important navigation links inside nav?Does each meaningful section have an appropriate heading?Should this use figure/figcaption?Should this date use <time>?| Element | Meaning |
|---|---|
<header> |
Introductory content |
<nav> |
Navigation links |
<main> |
Main content |
<section> |
Thematic grouping |
<article> |
Self-contained content |
<aside> |
Related/supporting content |
<footer> |
Footer information |
<figure> |
Self-contained media/content |
<figcaption> |
Figure caption |
<address> |
Contact information |
<time> |
Date/time |
HTML that uses elements according to their meaning and role rather than using generic containers for everything.
It improves:
<div> and <section>?#<div> is a generic container; <section> represents a meaningful thematic grouping.
<section> and <article>?#A section groups related content around a theme; an article represents self-contained content that can potentially stand independently.
Yes.
<article>
<section>
...
</section>
</article>Yes.
<section>
<article>
...
</article>
<article>
...
</article>
</section><header> only for the top of a webpage?#No.
A <header> can also introduce an article or section.
<footer> only for the bottom of the webpage?#No.
A <footer> can belong to a page, section, or article.
<nav>?#No.
<nav> is intended for significant navigation blocks, not every individual link.
<div>?#No.
Use <div> when no more appropriate semantic element exists.
Create a complete semantic blog page:
HEADER
NextGen Blog Logo
NAV
Home | AI | Programming | Cloud
MAIN
┌─────────────────────────────┐
│ │
│ ARTICLE │
│ │
│ Understanding AI Agents │
│ │
│ Published: Oct 1, 2026 │
│ │
│ ┌───────────────────────┐ │
│ │ Introduction │ │
│ └───────────────────────┘ │
│ │
│ ┌───────────────────────┐ │
│ │ How Agents Work │ │
│ └───────────────────────┘ │
│ │
└─────────────────────────────┘
ASIDE
Related Articles
FOOTER
© 2026 NextGen BlogTry to build it without CSS.
The objective is to see the semantic structure in the HTML itself.
Think of semantic HTML as describing a webpage to another developer, browser, search engine, and assistive technology without relying on visual appearance.
Instead of:
<div class="big-box">say:
<main>Instead of:
<div class="navigation">say:
<nav>Instead of:
<div class="blog-post">say:
<article>Instead of:
<div class="topic">say:
<section>But when the content has no special semantic meaning:
<div>is completely fine.
HTML should describe what content is, not merely how it looks.
Next we'll take semantic HTML further and learn how to design the complete architecture of a professional HTML document:
<html>, <head>, <body>Mark it as complete to track your mastery.