HTMLSemantic & Clean Markup

Semantic & Clean Markup

This page consolidates the semantic markup principles spread across earlier lessons into a single checklist. If you take one idea away from this whole tutorial, make it this: HTML elements carry meaning, and choosing the right one makes your pages more accessible, more maintainable, and easier for search engines and browsers to reason about.

Principle 1: The Right Element for the Job
Before reaching for a <div>, ask: "does an element already exist that means this?" HTML has purpose-built tags for buttons, navigation, articles, quotes, time, and dozens of other concepts. Using them for free gives you keyboard support, screen- reader semantics, and default styling you'd otherwise have to reimplement.

right-element.html

HTML
<!-- Wrong: a div pretending to be a button -->
<div class="btn" onclick="submit()">Submit</div>

<!-- Right: a real button, with focus/keyboard support built in -->
<button type="submit">Submit</button>

<!-- Wrong: bold text pretending to be a heading -->
<div><b>Section title</b></div>

<!-- Right: a real heading, which screen readers can navigate to -->
<h2>Section title</h2>
Principle 2: One Correct Heading Hierarchy
Headings form a document outline that both search engines and screen-reader users rely on. Use exactly one <h1> per page for its main topic, and never skip a level just to get a smaller font—control size with CSS instead.

heading-hierarchy.html

HTML
<h1>Building a Recipe App</h1>
  <h2>Getting Started</h2>
    <h3>Installing Dependencies</h3>
    <h3>Project Structure</h3>
  <h2>Core Features</h2>
    <h3>Search</h3>
    <h3>Favorites</h3>
Don't skip levels
Jumping from <h1> straight to <h4> because it "looks right" breaks the outline for anyone navigating by heading level. Fix the visual size with CSS, not by picking the wrong heading number.
Principle 3: Landmark Elements Define Page Regions
<header>, <nav>, <main>, <aside>, and <footer> mark out the major regions of a page. Screen readers can list all landmarks on a page, letting users jump straight to the one they need instead of tabbing through everything.

landmarks.html

HTML
<body>
  <header>
    <nav>...</nav>
  </header>

  <main>
    <article>...</article>
    <aside>...</aside>
  </main>

  <footer>...</footer>
</body>
Exactly one main
There should be exactly one visible <main> per page, containing the primary content unique to that page (not repeated headers, navigation, or sidebars).
Principle 4: Avoiding Div-Soup
"Div-soup" describes markup built entirely from generic <div> and <span> elements with classes doing all the descriptive work. It's a common result of copying a design tool's export directly into HTML without translating it to semantic tags.

div-soup-vs-semantic.html

HTML
<!-- Div-soup: meaning lives only in class names -->
<div class="post">
  <div class="post-title">Understanding Closures</div>
  <div class="post-meta">Published March 2, 2026</div>
  <div class="post-body">...</div>
</div>

<!-- Semantic: meaning lives in the elements themselves -->
<article>
  <h2>Understanding Closures</h2>
  <p><time datetime="2026-03-02">Published March 2, 2026</time></p>
  <div class="post-body">...</div>
</article>
Note that <div> isn't inherently bad—it's the correct choice precisely when there's no semantic meaning to convey, like a styling-only wrapper. The problem is using it everywhere, including places where a meaningful element exists.
Principle 5: Meaningful Link Text

Screen-reader users frequently pull up a list of every link on a page, out of surrounding context. "Click here" or "read more" tells them nothing in that list. Link text should describe the destination on its own.

link-text.html

HTML
<!-- Bad: meaningless out of context -->
<p>Our new pricing is live. <a href="/pricing">Click here</a> to view it.</p>

<!-- Good: descriptive on its own -->
<p>Our new pricing is live. <a href="/pricing">View the new pricing</a>.</p>
Principle 6: Meaningful alt Text
Every content image needs an alt attribute describing what it conveys, not what it literally shows. Purely decorative images should use alt="" so screen readers skip them instead of announcing an unhelpful filename.

alt-text.html

HTML
<!-- Bad: describes the file, not the content -->
<img src="chart-q3.png" alt="chart-q3.png" />

<!-- Good: describes what the image conveys -->
<img src="chart-q3.png" alt="Q3 revenue grew 18% quarter over quarter" />

<!-- Decorative image: empty alt so it's skipped by screen readers -->
<img src="divider-swirl.svg" alt="" />
Consolidated Checklist

Principle

Check

Right element

Would a native tag give you free semantics/behavior?

Heading hierarchy

Exactly one h1, no skipped levels

Landmarks

header/nav/main/aside/footer used, one main

No div-soup

Content-bearing elements use semantic tags

Link text

Meaningful on its own, out of context

Alt text

Describes meaning; empty for decorative images

  • Semantic HTML is free accessibility, free SEO signal, and free browser behavior.

  • Class names alone are not a substitute for meaningful elements.

  • When no semantic element fits, a styled <div> or <span> is the correct, honest choice.

A useful gut check
If you deleted every class and ID attribute from your markup and looked only at the raw tag names, would the page's structure still make sense? That's a solid working definition of "semantic."
Validate periodically
A markup validator catches structural mistakes semantic review might miss—see the dedicated validation page for a walkthrough of the W3C Markup Validator.