The Semantic HTML Vocabulary
A self-demonstrating field guide — every element on this page is its own example
Published · Reading time · Filed under HTML
This document is written under one rule: the markup carries all the meaning. The styling you see is the site's theme laid over honest structure — switch the styled view off in the header to read this page exactly as the browser's default stylesheet renders it. Turn on a screen reader, or open the accessibility tree in devtools — the structure you hear is the structure you see, because the page is its structure.
Inline text semantics
The words you are reading sit inside a <p>. When a phrase
carries stress that changes meaning, it takes emphasis; when it carries
weight, it is strongly important. A keyword merely
drawn to your attention uses <b>, and text in an
alternate voice — like the taxonomic name Homo sapiens — uses
<i>.
A term being defined, such as semantics (the
meaning of markup, as opposed to its appearance), is a <dfn>.
Abbreviations expand on hover: the W3C
and the WHATWG
maintain the specs. Titles of works take <cite>:
HTML: The Living Standard.
Computer-speak has four distinct elements. Source fragments use
document.querySelector(). Variables and placeholders use
elementName. Program output uses Document is valid. 0 errors.
Keyboard input uses Ctrl+Shift+I —
note the nested <kbd> per key.
Machine-readable values: the product Field Guide,
second edition ships on .
Search engines read the value and datetime attributes;
humans read the prose. A search hit would be highlighted like this.
Fine print is set with terms and conditions apply, chemistry with
H2O, math with E = mc2, and a price that no longer applies
is struck: $49.00 now $29.00.
Long unbroken tokens accept break opportunities with <wbr>:
https://html-tags.com/.
A proper-noun mark in Chinese uses <u>, its only good use:
北京是中国的首都。
Grouping and lists
The three list families
Ordered steps (<ol>, here counting down with
reversed):
- Validate the document
- Check the accessibility tree
- Write the markup
An unordered set (<ul>) with a nested list:
- Sectioning elements
<article><section>
- Landmark elements
A toolbar of commands is a <menu>:
Name–value pairs
- Element
<dl>- Purpose
- Glossaries, metadata blocks, spec sheets, FAQs
- Children
<dt>terms and<dd>descriptions
Self-contained referenced content
<figure>
<pre><code>…a code listing…</code></pre>
<figcaption>Figure 1 — captions belong to figures</figcaption>
</figure>
<figure> holding a code listing,
demonstrating itself.Outline depth
Headings reach six levels. The level is chosen by position in the outline, never by desired size:
Level four — a sub-topic
Reached from a level-three subsection, one step at a time.
Level five — a fine-grained point
Rare in practice; a hint the document is deeply structured.
Level six — the deepest rung
If you find yourself wanting a seventh level, restructure the document instead.
Line breaks as content
Poetry keeps its line breaks as content, with <br>:
Markup is meaning,
styling is skin;
strip off the stylesheet —
the truth is within.
Quotations and edits
Inline quotation marks come from the browser, localized by lang:
the spec says a section is a thematic
grouping of content, typically with a heading
.
Semantic HTML provides a solid foundation on which all other web technologies are built.
Tracked changes: the deadline moved from
July 1 to
July 15.
Internationalization elements
Every language switch is marked. She whispered
c'est la vie and moved on. A German proverb:
Übung macht den Meister
— notice the quotation marks change
with the language.
East Asian pronunciation uses ruby annotations with parenthesis fallback: 東京 (Tokyo).
Bidirectional isolation protects layout from unknown-direction text. Top
contributors: אורי — 12 edits, سارة — 9 edits,
Åsa — 7 edits. Without <bdi>, the numbers can
visually attach to the wrong name. A forced override:
this sentence renders right-to-left.
Do-not-translate spans use the translate attribute: the project
is called Field Guide in every locale.
Tabular data
| Era | Representative elements | Count shown |
|---|---|---|
| HTML5 (2008–2014) | article, nav, time, figure |
4 |
| Living Standard (2015–2022) | dialog, details, picture, slot |
4 |
| Modern era (2023–2026) | search, selectedcontent, geolocation, fencedframe |
4 |
| Total | 12 |
Media and embedded content
<picture> negotiating format, with an
image map: the circle itself is a clickable <area>.<svg> with
role="img" and an internal <title>.<math> (MathML Core).Audio and video players with caption tracks (the sources are real ten-second test clips, so the players — and the captions track — actually work):
Transcript
Welcome to the field guide. In this recording we walk the document tree from root to leaf…
An embedded document via <iframe srcdoc>:
Forms
Gauges, progress, and results
Sum of 6 and 36 is — <output> marks a
result even when computed at authoring time.
JS-free interactivity
Exclusive accordion — <details name>
Why no CSS at all?
To prove the structure stands on its own. Default browser styling is the shared baseline every user agent — visual or not — understands.
Why does opening this close the other?
Both <details> share name="faq", which makes
them a mutually exclusive group. No script involved.
Declarative popover
Baseline: a feature supported in the current and previous versions of all major browsers. Press Esc or click outside to dismiss — the browser handles it.
Non-modal dialog
Frontier elements — shown as code, not run
Three 2026 elements are experimental (Chromium-first, not Baseline) and require JavaScript, so a static page demonstrates them as listings.
<geolocation watch>
<button id="geo-fallback" type="button">Use my location</button>
</geolocation>
<script>
const geo = document.querySelector("geolocation");
geo.addEventListener("location", () => {
if (geo.position) console.log(geo.position.coords);
});
</script>
<geolocation>: the browser owns the
permission UI; your code listens for the location event.<select>
<button>
<selectedcontent></selectedcontent>
</button>
<option>🍎 Apple</option>
<option>🍊 Orange</option>
</select>
<!-- Activates only with CSS: select { appearance: base-select; } -->
<selectedcontent> mirrors the chosen
option into the closed select’s button.<fencedframe id="ad-slot" width="640" height="320"
title="Advertisement, selected privately"></fencedframe>
<script>
const config = await navigator.runAdAuction({
seller: "https://ssp.example",
decisionLogicUrl: "https://ssp.example/decision-logic.js",
interestGroupBuyers: ["https://dsp-a.example"],
resolveToConfig: true,
});
document.querySelector("#ad-slot").config = config;
</script>
<fencedframe>: the embedder can load
the winning ad but can never learn its URL.