🏷️ Semantic HTML Elements
You can build an entire website out of nothing but <div> tags — and it will look fine. But it will be invisible to screen readers, harder for search engines to understand, and a nightmare for the next developer to read. Semantic HTML fixes all three by giving your content meaning, not just shape.
Week 1 · Day 2 (Tuesday: HTML Fundamentals) · Lecture 2
🎯 Learning Objectives
By the end of this lesson, you will be able to:
- Explain what "semantic" means and why it beats
<div>soup - Lay out a page with the structural landmarks:
header,nav,main,article,section,aside, andfooter - Choose correctly between
<article>and<section> - Build a valid document outline with the
h1–h6heading hierarchy - Apply inline semantics like
<strong>,<em>,<time>, and<abbr> - Mark up images, quotes, and figures accessibly
Estimated Time: 60 minutes
Practice: Convert a page of anonymous divs into a meaningful, semantic blog layout.
In This Lesson
What Is Semantic HTML?
Imagine reading a book printed as one unbroken block of text — no chapters, no headings, no paragraphs. You could still read every word, but finding anything would be exhausting. Semantic HTML is the difference: it uses tag names that describe what the content is, so both humans and machines can navigate it.
Compare these two versions of the same navigation bar:
<!-- Non-semantic: works visually, means nothing -->
<div class="top">
<div class="menu">
<div class="link">Home</div>
</div>
</div>
<!-- Semantic: the tags tell the story -->
<header>
<nav>
<a href="/">Home</a>
</nav>
</header>
Both render identically. But only the second tells a screen reader "this is the site header, and this is the navigation," lets a keyboard user jump straight to it, and signals to search engines which links form your main menu.
Why it matters
- Accessibility: Screen readers expose semantic elements as "landmarks" users can jump between
- SEO: Search engines weight content inside meaningful tags more sensibly
- Maintainability:
<article>reads better than<div class="art-wrap-2"> - Future-proofing: New tools and browsers understand standard elements automatically
Structural Landmarks
HTML5 gives you a set of container elements that mark the major regions of a page — the same way a newspaper has a masthead, sections, sidebars, and a footer. Screen readers call these landmarks, and users navigate between them directly.
| Element | What it marks |
|---|---|
<header> | Introductory content — logo, site title, sometimes the nav |
<nav> | A block of major navigation links |
<main> | The page's primary, unique content — exactly one per page |
<article> | A self-contained piece that could stand alone (a post, a card) |
<section> | A thematic grouping of related content, usually with a heading |
<aside> | Tangential content — sidebars, pull quotes, related links |
<footer> | Closing content — copyright, contact, secondary links |
Here's a skeleton page using all of them together:
<body>
<header>
<h1>My Blog</h1>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
</header>
<main>
<article>
<h2>A Post Title</h2>
<p>The content of the post...</p>
</article>
</main>
<aside>
<h2>Related</h2>
<a href="/other">Another post</a>
</aside>
<footer>
<p>© 2026 My Blog</p>
</footer>
</body>
⚠️ One <main>, and don't over-<nav>
There should be exactly one <main> per page — it's the "skip to content" target. And <nav> is for major navigation blocks only; a stray link inside a paragraph does not need to be wrapped in <nav>.
Article vs. Section
This is the pairing that trips up almost everyone. Both group content — so which do you reach for?
<article>— use it when the content would make sense on its own, lifted out of the page. A blog post, a news story, a product card, a single comment. The "could I syndicate this in an RSS feed?" test is a good one.<section>— use it to group related content within a larger whole, almost always introduced by a heading. "Our Services," "Chapter 2," "Frequently Asked Questions."
<article>
<h2>How to Brew Better Coffee</h2>
<section>
<h3>Choosing Beans</h3>
<p>...</p>
</section>
<section>
<h3>Grinding</h3>
<p>...</p>
</section>
</article>
💡 Rule of thumb: An article is a whole thing you could hand to someone by itself. A section is a labelled chunk inside a bigger thing. It's perfectly normal for articles to contain sections — and occasionally the reverse.
💡 When neither fits, use a <div>
Semantic elements describe meaning. If you only need a box to hook some CSS onto — a wrapper for layout with no meaning of its own — a plain <div> is the correct choice. Don't force semantics where there are none.
Headings & Outline
Headings <h1> through <h6> aren't just "big bold text" — they create a document outline, like a table of contents built into your markup. Screen-reader users routinely pull up a list of all headings to jump around a page, so getting the hierarchy right is a genuine accessibility feature, not a cosmetic one.
<h1>Page Title (one per page)</h1>
<h2>Major Section</h2>
<h3>Subsection</h3>
<h3>Another Subsection</h3>
<h2>Another Major Section</h2>
⚠️ Don't skip levels, and don't pick by size
Go h1 → h2 → h3 in order; never jump from h1 straight to h4 because it "looks right." If a heading is too big or too small, that's a job for CSS, not for choosing a different heading level. The level communicates structure; the styling is separate.
Text Content Elements
Beyond headings, a handful of block-level elements organize the bulk of your text.
Paragraphs and lists
<p>A paragraph is the default container for a block of text.</p>
<!-- Unordered list: order doesn't matter -->
<ul>
<li>Coffee</li>
<li>Tea</li>
</ul>
<!-- Ordered list: sequence matters -->
<ol>
<li>Boil the water</li>
<li>Add the grounds</li>
</ol>
<!-- Description list: term/definition pairs -->
<dl>
<dt>HTML</dt>
<dd>HyperText Markup Language</dd>
</dl>
Quotes
Use <blockquote> for a standalone quoted passage and <cite> to name its source. The cite attribute can point to the original URL.
<blockquote cite="https://www.w3.org/People/Berners-Lee/">
<p>The Web is for everyone.</p>
<footer>— <cite>Tim Berners-Lee</cite></footer>
</blockquote>
Inline Semantics
Inline elements add meaning to small stretches of text within a paragraph. The key insight: choose them for meaning, not appearance. <strong> and <b> both look bold, but only <strong> tells assistive tech "this is important."
Emphasis and importance
<p>This word is <em>emphasized</em> (usually italic).</p>
<p>This word is <strong>important</strong> (usually bold).</p>
Useful inline elements
<!-- Abbreviation with an expansion on hover -->
<abbr title="HyperText Markup Language">HTML</abbr>
<!-- Machine-readable date/time -->
<time datetime="2026-01-15">January 15, 2026</time>
<!-- Highlighted / marked text -->
Results for <mark>semantic HTML</mark>
<!-- Inline code -->
Call the <code>console.log()</code> function.
<!-- Chemistry and math -->
H<sub>2</sub>O and E = mc<sup>2</sup>
Links
The anchor <a> is the "hyper" in HyperText. Its href can point to many kinds of destination:
<a href="https://example.com" target="_blank" rel="noopener">External site</a>
<a href="#section1">Jump to a section on this page</a>
<a href="mailto:hello@example.com">Email us</a>
<a href="tel:+15551234567">Call us</a>
💡 Security note: When you open a link in a new tab withtarget="_blank", addrel="noopener". It prevents the new page from gaining scripting access back to yours.
Media & Figures
Images with meaningful alt text
Every content image needs an alt attribute describing it — this is what a screen reader announces and what displays if the image fails to load.
<img src="team.jpg" alt="Four developers collaborating around a laptop"
width="800" height="600">
💡 Purely decorative image? Give it an empty alt="". That tells assistive tech to skip it, rather than announcing a distracting filename.
Figure and figcaption
When an image, chart, or code sample needs a caption, wrap the pair in a <figure>. It ties the caption to the content programmatically.
<figure>
<img src="chart.png" alt="Bar chart of quarterly sales, up 25%">
<figcaption>Quarterly sales rose 25% over last year.</figcaption>
</figure>
Audio and video
HTML5 plays media natively. Offer multiple <source> formats so different browsers each find one they support, and include a caption <track> for accessibility.
<video controls width="640" poster="thumbnail.jpg">
<source src="clip.mp4" type="video/mp4">
<source src="clip.webm" type="video/webm">
<track kind="captions" src="captions_en.vtt" srclang="en" label="English">
Your browser doesn't support embedded video.
</video>
Practice & Quiz
🏋️ Exercise: De-soup a blog post
Goal: The markup below works visually but is meaningless <div> soup. Rewrite it using semantic elements — landmark containers, a proper heading, and a machine-readable date.
<div class="top">
<div class="title">My Blog</div>
<div class="menu"><div class="item">Home</div></div>
</div>
<div class="content">
<div class="post">
<div class="post-title">My First Post</div>
<div class="date">January 15, 2026</div>
<div class="body">Hello, world!</div>
</div>
</div>
💡 Hint
The outer top is a <header> containing a heading and a <nav>. The content is <main>. Each post is an <article>. Wrap the date in a <time datetime="...">.
✅ Solution
<header>
<h1>My Blog</h1>
<nav>
<a href="/">Home</a>
</nav>
</header>
<main>
<article>
<h2>My First Post</h2>
<p>Published on
<time datetime="2026-01-15">January 15, 2026</time>
</p>
<p>Hello, world!</p>
</article>
</main>
Same appearance, but now every region is a landmark and the date is machine-readable.
🎯 Quick Quiz
Question 1: How many <main> elements should a single page have?
Question 2: You're marking up a blog post that could be republished on its own in an RSS feed. Which element fits best?
Question 3: Which is the correct way to mark decorative image so screen readers skip it?
Best Practices & Pitfalls
✅ Do
- Reach for a semantic element before a
<div>— use the div only when no meaning applies - Keep exactly one
<main>and one logical<h1>per page - Follow the heading hierarchy in order, without skipping levels
- Write descriptive
alttext for meaningful images,alt=""for decorative ones - Choose
<strong>/<em>for meaning, and leave visual weight to CSS
❌ Don't
- Build the whole page from
<div>s ("div soup") - Pick heading levels by how big they look
- Wrap every single link in a
<nav> - Use a
<section>with no heading just to group things — reach for<div>there
✅ The one-question test
Before typing <div>, ask: "Is there a tag that describes what this is?" If yes — header, nav, article, figure, time — use it. If genuinely not, <div> is the right, honest choice.
Summary
🎉 Key Takeaways
- Semantic HTML describes what content means, improving accessibility, SEO, and readability
- The landmarks — header, nav, main, article, section, aside, footer — carve a page into navigable regions
- Article = self-contained; section = a labelled group within a whole; div = meaningless wrapper
- Headings build an outline: one
h1, no skipped levels, size handled by CSS - Inline tags like
strong,em,time,abbradd meaning to small spans of text
📚 Additional Resources
🚀 What's Next?
You can now structure and describe content meaningfully. Next we make that content interactive: the following lesson covers forms and input types — how to collect information from users with text fields, checkboxes, dropdowns, and HTML5's built-in validation.
🏷️ Meaning, not just markup!
Your pages now speak to browsers, search engines, and assistive tech alike. That's the mark of a professional front-end.