Skip to main content
The FTC fined the leading overlay provider $1M for deceptive claims. Learn why it matters (opens in new tab)
Developer Guides

Semantic HTML: the accessibility foundation

September 10, 20258 min read

Before you reach for ARIA, before you add keyboard event handlers, before you adjust tab order — fix your HTML. Semantic HTML is the most efficient way to provide accessibility information to browsers and assistive technologies. When you use the right element for the job, you get keyboard behavior, role semantics, and state management for free.

Landmark elements

HTML5 landmark elements create a navigation structure that screen reader users rely on. The key ones are:

  • <header> — site or section header; maps to the "banner" landmark role
  • <nav> — navigation block; maps to the "navigation" role. Use aria-label to distinguish multiple navs.
  • <main> — the primary content area; maps to the "main" role. Only one per page.
  • <aside> — complementary content; maps to the "complementary" role.
  • <footer> — site or section footer; maps to the "contentinfo" role.
  • <section> — generic section; only becomes a landmark if it has an accessible name via aria-labelledby.

Headings

The heading hierarchy (h1–h6) is the most commonly abused semantic structure. Screen reader users navigate pages by jumping between headings. Every page should have exactly one h1 (the page title), and headings should not skip levels. Never use heading elements for visual styling — use CSS instead. Never style non-heading text with heading-sized fonts without using an actual heading element.

Interactive elements

Use native interactive elements wherever possible. A <button> comes with keyboard focus, activation via Enter and Space, the "button" ARIA role, and built-in disabled state handling. A <div onClick> has none of these. Similarly, <a href> is for navigation; <button> is for actions. Using the wrong one requires you to replicate all the missing semantics manually.

The cost of ignoring semantics

<!-- This requires: tabindex, role, keydown handler, aria-pressed, focus styles -->
<div class="btn" onclick="handleClick()">Save</div>

<!-- This gives you all of that for free -->
<button type="button" onclick="handleClick()">Save</button>

Form elements

Every form input must have an associated label — either using <label for="id">, wrapping the input inside a <label>, or using aria-label/aria-labelledby as a last resort. Never rely on placeholder text as a label; placeholders disappear on input, have low contrast, and are not consistently announced by screen readers. Use <fieldset> and <legend> to group related inputs (e.g., radio groups, checkboxes).

Put it into practice

See exactly where your site stands against WCAG 2.2.

Free scan on any public URL. Full report in under two minutes.