Semantic HTML: The Elements That Do Work For You
Which HTML elements carry real semantics, what assistive technology and search engines do with them, and the div-soup patterns worth replacing.
Table of contents
- Landmarks give assistive tech a map
- Elements that replace JavaScript entirely
- Elements that carry meaning
- Headings are an outline, not font sizes
- Buttons versus links
- Forms: labels are not optional
- Frequently asked questions
- Does semantic HTML improve SEO?
- When should I use <section> versus <div>?
- Is ARIA a substitute for semantic HTML?
- How do I test this?
- Related reading
- References
Semantic HTML is not a style preference. Each element below provides behaviour, accessibility semantics or both — things you would otherwise write yourself, with ARIA, and get subtly wrong.
Landmarks give assistive tech a map#
<body>
<header>
<!-- banner landmark -->
<nav aria-label="Main">…</nav>
</header>
<main>
<!-- one per page -->
<article>…</article>
<aside>…</aside>
</main>
<footer>…</footer>
<!-- contentinfo landmark -->
</body>Screen-reader users navigate by landmark — jumping straight to main or cycling through navigation regions. A page of <div>s has no landmarks, so that entire navigation mode is unavailable and users must read linearly.
Two rules: exactly one <main> per page, and label multiple <nav> elements with aria-label so they are distinguishable ("Main", "Footer", "Breadcrumb").
Elements that replace JavaScript entirely#
<details> / <summary> is a disclosure widget with keyboard support, correct expanded/collapsed state in the accessibility tree, and — importantly — content that exists in the DOM whether open or closed:
<details>
<summary>How is reading time calculated?</summary>
<p>At 238 words per minute…</p>
</details>No JavaScript, no aria-expanded to keep in sync, and the content is crawlable. For an FAQ section marked up with FAQPage structured data, that last point matters: Google requires the answers to be present in the page.
<dialog> gives you a real modal:
<dialog id="confirm">
<form method="dialog">
<p>Delete this item?</p>
<button value="cancel">Cancel</button>
<button value="confirm">Delete</button>
</form>
</dialog>document.getElementById('confirm').showModal();showModal() provides a focus trap, Escape-to-close, an inert background, and focus restoration on close. Hand-rolled modals get at least one of those wrong almost every time.
Elements that carry meaning#
<!-- Machine-readable date, used by search engines and screen readers -->
<time datetime="2026-07-28">28 July 2026</time>
<!-- A range, with accessible min/max -->
<progress value="70" max="100">70%</progress>
<!-- Definition list: term/description pairs, not a generic list -->
<dl>
<dt>LCP</dt>
<dd>Largest Contentful Paint</dd>
</dl>
<!-- Emphasis with meaning, not just italics -->
<em>stress emphasis</em> vs <i>a different voice or term</i>
<strong>importance</strong> vs <b>stylistically offset</b><time datetime> is the one with direct SEO value: it gives a crawler an unambiguous date rather than asking it to parse "28 July 2026".
Headings are an outline, not font sizes#
<h1>Page title</h1>
<!-- one per page -->
<h2>Section</h2>
<h3>Subsection</h3>
<h2>Another section</h2>Do not skip levels to get a smaller font — use CSS for size. Screen-reader users list headings to understand page structure, and a jump from h2 to h4 reads as a missing section.
Buttons versus links#
<!-- Navigates somewhere → link -->
<a href="/tools">Browse tools</a>
<!-- Performs an action → button -->
<button type="button" onclick="copy()">Copy</button>This distinction is functional, not stylistic. A link supports middle-click, open-in-new-tab, right-click-copy-URL and crawling; a button is activated by both Enter and Space. A <div onclick> supports none of it and is invisible to keyboard users.
If a link must look like a button, style the anchor — do not swap the element.
Forms: labels are not optional#
<label for="email">Email address</label>
<input id="email" name="email" type="email" autocomplete="email" required />The for/id pairing makes the label clickable and makes the field announce its name. autocomplete with the correct token lets browsers and password managers fill accurately — a real usability win that costs one attribute.
Placeholder text is not a label: it disappears on focus, usually fails contrast requirements, and is not reliably announced.
Frequently asked questions#
Does semantic HTML improve SEO?#
Indirectly and genuinely. Crawlers use main, article, headings and time to understand structure and extract dates. There is no ranking bonus for using <section>, but there is a real cost to a page a crawler cannot parse.
When should I use <section> versus <div>?#
<section> needs an accessible name (usually a heading) to be useful; without one it adds nothing over a <div>. Use <div> freely for pure styling hooks — that is what it is for.
Is ARIA a substitute for semantic HTML?#
No. The first rule of ARIA is not to use ARIA when a native element will do. Native elements bring behaviour; ARIA only relabels.
How do I test this?#
Tab through the page with the keyboard only, then run through it with a screen reader (VoiceOver on macOS, NVDA on Windows). Automated tools catch perhaps 30% of accessibility issues; keyboard testing catches most of the rest.
Related reading#
- Web Accessibility Checklist
- Core Web Vitals
- Tidy markup with the HTML Formatter.