HTML & CSS

Semantic HTML

Semantic tags describe what content means, not just how it looks. They make pages easier to read, better for SEO, and usable with screen readers. Here's every semantic element, what it's for, and a live example.

New to semantic tags? Read the visual lesson

Why it matters

Meaning over appearance

A <div> says nothing about its content — it's a generic box. A <nav> tells the browser, search engines, and assistive technology “this is the navigation.” Same pixels, far more meaning.

The non-semantic way

<div class="header">...</div>
<div class="nav">...</div>
<div class="main">
  <div class="article">...</div>
</div>
<div class="footer">...</div>

The semantic way

<header>...</header>
<nav>...</nav>
<main>
  <article>...</article>
</main>
<footer>...</footer>
Rule of thumb: reach for a semantic tag first. Only fall back to <div> or <span> when no semantic element fits.
Page structure

The layout landmarks

These seven elements describe the major regions of a page. Screen readers expose them as “landmarks” users can jump between.

<header> — site title / logo
<nav> — main navigation
<main> — the page's unique content
<article> — a self-contained piece
<section> — a thematic grouping
<aside> — related / sidebar
<body>
  <header>
    <h1>My Site</h1>
    <nav>
      <a href="/">Home</a>
      <a href="/about">About</a>
    </nav>
  </header>

  <main>
    <article>
      <h2>Blog post title</h2>
      <section>
        <h3>Part one</h3>
        <p>...</p>
      </section>
    </article>

    <aside>
      <h2>Related links</h2>
    </aside>
  </main>

  <footer>
    <p>&copy; 2026 My Site</p>
  </footer>
</body>

A real article + aside, rendered

Why semantic markup wins

Posted

This whole box is an <article> — it could stand on its own in a feed.

Written by Dr. G
<article style="border:1px solid #d2d2d7;border-radius:10px;padding:16px;background:#fff;font-family:-apple-system,'Segoe UI',Roboto,sans-serif;">
  <header style="border:0;padding:0;background:none;">
    <h3 style="margin:0;color:#1d1d1f;">Why semantic markup wins</h3>
    <p style="margin:4px 0 0;font-size:.82rem;color:#6b7280;">Posted <time datetime="2026-05-29">May 29, 2026</time></p>
  </header>
  <p style="color:#374151;">This whole box is an <code style="background:#eef6f0;color:#0f766e;padding:2px 6px;border-radius:5px;">&lt;article&gt;</code> — it could stand on its own in a feed.</p>
  <aside style="background:#f5f5f7;border-left:4px solid #a855f7;border-radius:8px;padding:10px 14px;">
    <strong style="color:#1d1d1f;">Aside:</strong> <span style="color:#374151;">this related note is an <code style="background:#f3e8ff;color:#7c3aed;padding:2px 6px;border-radius:5px;">&lt;aside&gt;</code>.</span>
  </aside>
  <footer style="text-align:left;padding:8px 0 0;border:0;background:none;margin:8px 0 0;font-size:.82rem;color:#6b7280;">Written by Dr. G</footer>
</article>
TagUse it for
<header>Introductory content for the page or a section — logo, title, intro nav.
<nav>A block of major navigation links. You can have more than one (primary, footer).
<main>The one unique main content area. Use only once per page.
<section>A thematic grouping of content, usually with its own heading.
<article>A self-contained piece that could stand alone — a post, card, or comment.
<aside>Content tangential to the main content — sidebars, pull quotes, ads.
<footer>Closing content for the page or a section — copyright, contact, links.
section vs. article: if the chunk would make sense on its own (you could syndicate it in an RSS feed), it's an <article>. If it's just a themed grouping inside a larger whole, it's a <section>.
Headings

h1 through h6

Headings build the document outline. Use them in order — don't skip levels — and pick them for rank, not size. Style the size with CSS.

h1 — Page title

h2 — Major section

h3 — Subsection

h4 — Minor heading

h5 — Smaller still
h6 — Smallest heading
<h1>Page title</h1>
<h2>Major section</h2>
<h3>Subsection</h3>
<h4>Minor heading</h4>
<h5>Smaller still</h5>
<h6>Smallest heading</h6>
One h1 per page is the safest habit — it names the whole document. Never jump from <h2> straight to <h4>.
Media

figure & figcaption

A <figure> groups an image, diagram, or code sample with its caption. The <figcaption> is the caption, tied to the figure for screen readers.

A randomly generated landscape photo
Figure 1. A caption describes the image above.
<figure>
  <img src="chart.png" alt="Sales by quarter">
  <figcaption>Figure 1. Quarterly sales, 2026.</figcaption>
</figure>
Lists

Ordered, unordered & description lists

Lists are semantic too — they tell assistive tech “these items belong together” and announce how many there are. Pick the type by meaning: order matters or it doesn't, or you're pairing terms with definitions.

Unordered list — order doesn't matter

  • Apples
  • Bread
  • Coffee
<ul>
  <li>Apples</li>
  <li>Bread</li>
  <li>Coffee</li>
</ul>

Ordered list — sequence matters

  1. Preheat the oven
  2. Mix the batter
  3. Bake for 20 minutes
<ol>
  <li>Preheat the oven</li>
  <li>Mix the batter</li>
  <li>Bake for 20 minutes</li>
</ol>

Description list — term + definition pairs

HTML
The structure and content of a web page.
CSS
The styling and visual presentation.
<dl>
  <dt>HTML</dt>
  <dd>The structure and content of a web page.</dd>
  <dt>CSS</dt>
  <dd>The styling and visual presentation.</dd>
</dl>
TagUse it for
<ul>An unordered list — bullets where sequence is irrelevant.
<ol>An ordered list — numbered steps where sequence matters.
<li>A single list item inside a <ul> or <ol>.
<dl>A description list — a set of term/definition groups.
<dt>A description term (the word being defined).
<dd>A description detail (the definition of the term).
Don't fake a list. A stack of <div>s or <br>-separated lines looks like a list but isn't one — screen readers won't announce the item count. Use real list tags.
Text-level meaning

Inline semantic tags

These mark up meaning within a sentence — emphasis, importance, quotes, dates, and more. They beat a styled <span> because they carry meaning.

You must save before you refresh the page.

Search results for semantic HTML are highlighted.

The launch is scheduled for .

The W3C sets web standards.

As The Elements of Typographic Style notes, readability comes first.

A long, block-level quotation goes in a blockquote.

She said, a short inline quote uses the q tag, and smiled.

Press Ctrl + S to save. The program printed Done.

The variable x stores the result. Delete old text new text.

Water is H2O, and 52 equals 25.

A byte is eight bits. The function greet() prints a message.

That feature is discontinued. Terms and conditions apply.

Contact: prof@example.edu
<p>You <strong>must</strong> save before you <em>refresh</em> the page.</p>
<p>Search results for <mark>semantic HTML</mark> are highlighted.</p>
<p>The launch is scheduled for <time datetime="2026-07-01">July 1, 2026</time>.</p>
<p>The <abbr title="World Wide Web Consortium">W3C</abbr> sets web standards.</p>
<p>As <cite>The Elements of Typographic Style</cite> notes, readability comes first.</p>
<blockquote style="border-left:4px solid #10b981;margin:0;padding:6px 14px;color:#374151;">A long, block-level quotation goes in a blockquote.</blockquote>
<p>She said, <q>a short inline quote uses the q tag</q>, and smiled.</p>
<p>Press <kbd>Ctrl</kbd> + <kbd>S</kbd> to save. The program printed <samp>Done.</samp></p>
<p>The variable <var>x</var> stores the result. Delete <del>old text</del> <ins>new text</ins>.</p>
<p>Water is H<sub>2</sub>O, and 5<sup>2</sup> equals 25.</p>
<p>A <dfn>byte</dfn> is eight bits. The function <code>greet()</code> prints a message.</p>
<p>That feature is <s>discontinued</s>. <small>Terms and conditions apply.</small></p>
<address style="font-style:normal;color:#374151;">Contact: <a href="mailto:prof@example.edu">prof@example.edu</a></address>
TagMeaning
<strong>Strong importance / seriousness (renders bold).
<em>Stress emphasis that changes meaning (renders italic).
<mark>Highlighted / relevant text, like a search match.
<time>A date or time; datetime gives a machine-readable value.
<abbr>An abbreviation; title gives the full term.
<cite>The title of a referenced work.
<blockquote>A block-level quotation from another source.
<q>A short, inline quotation.
<kbd>Keyboard input the user should type.
<samp>Sample output from a program.
<var>A variable or placeholder name.
<del> / <ins>Removed text / inserted text (edits).
<sub> / <sup>Subscript / superscript — chemical formulas, exponents, footnote marks.
<dfn>The defining instance of a term being introduced.
<code>A fragment of computer code (renders monospace).
<s>Text that is no longer accurate or relevant (struck through).
<small>Side comments and fine print, like legal text.
<address>Contact information for the nearest article or page.
Interactive

details & summary

A native disclosure widget — an expandable section with no JavaScript. The <summary> is the always-visible label; clicking it reveals the rest.

What is semantic HTML? (click to expand)

Using tags that describe the meaning of content rather than just its appearance.

<details style="border:1px solid #d2d2d7;border-radius:8px;padding:10px 14px;">
  <summary style="cursor:pointer;font-weight:600;">What is semantic HTML? (click to expand)</summary>
  <p style="margin:8px 0 0;color:#374151;">Using tags that describe the meaning of content rather than just its appearance.</p>
</details>
Status & output

progress, meter & output

These elements carry a value the browser and assistive tech understand — a task's completion, a measurement on a scale, or a calculated result. Far more meaningful than a styled bar.

Upload progress (a task in motion):

70%

Disk usage (a measurement on a known scale):

80%

3 + 4 = 7 (a calculated result)

<p style="color:#374151;margin-bottom:6px;">Upload progress (a task in motion):</p>
<progress value="70" max="100" style="width:100%;">70%</progress>

<p style="color:#374151;margin:14px 0 6px;">Disk usage (a measurement on a known scale):</p>
<meter value="0.8" min="0" max="1" style="width:100%;">80%</meter>

<p style="color:#374151;margin:14px 0 0;">3 + 4 = <output style="font-weight:700;color:#0f766e;">7</output> (a calculated result)</p>
TagUse it for
<progress>How far along a task is — a download, an upload, a multi-step form.
<meter>A scalar measurement within a known range — disk space, a score, a rating.
<output>The result of a calculation or user action, often from a form.
progress vs. meter: use <progress> for something completing over time, and <meter> for a static gauge reading. They look similar but mean different things.
Interactive

dialog

A native modal or popup window. <dialog> handles focus trapping, the backdrop, and the Esc-to-close behavior for you — things that used to take a lot of JavaScript.

Native dialog

No JavaScript library required — this is built into HTML.

<dialog id="box" style="border:0;border-radius:12px;padding:24px;max-width:340px;box-shadow:0 20px 50px rgba(0,0,0,.3);">
  <h3 style="margin:0 0 8px;color:#1d1d1f;">Native dialog</h3>
  <p style="color:#374151;margin:0 0 16px;">No JavaScript library required — this is built into HTML.</p>
  <button onclick="box.close()" style="background:#e5e7eb;color:#1d1d1f;border:0;border-radius:8px;padding:8px 16px;font-weight:600;cursor:pointer;">Close</button>
</dialog>

<button onclick="box.showModal()" style="background:#0f766e;color:#fff;border:0;border-radius:8px;padding:10px 18px;font-weight:600;cursor:pointer;">Open</button>
The fallbacks

When div & span are still right

<div> (block) and <span> (inline) carry no meaning — that's their job. Use them purely for styling or scripting hooks when no semantic element applies, like a layout wrapper or a colored word inside a sentence.

<div class="grid-wrapper">...</div>        <!-- layout only -->
<p>Total: <span class="price">$42</span></p>  <!-- style one word -->
Related: see the Accessibility tutorial for how landmarks help screen-reader users, and Intro to HTML for the basics.