Skip to main content

Semantic HTML

Semantic HTML is the foundation of web accessibility. When you use the correct HTML elements, browsers and assistive technologies automatically understand the structure and purpose of your content — no extra work required.

Why Semantics Matter

Screen readers and other assistive tools rely on the HTML element type to communicate meaning. A <button> announces itself as a button. A <nav> announces itself as navigation. A <div> announces itself as... nothing.

<!-- Bad: div with click handler -->
<div onclick="submitForm()">Submit</div>

<!-- Good: native button -->
<button type="submit">Submit</button>

The native <button> gives you focus management, keyboard activation (Enter and Space), and screen reader announcement for free. The <div> version requires you to manually recreate all of that.

Landmarks

Landmarks help screen reader users jump between major sections of a page. Use these structural elements:

<header>Site branding and primary navigation</header>
<nav>Navigation links</nav>
<main>Primary page content</main>
<aside>Sidebar or supplementary content</aside>
<footer>Site footer and secondary links</footer>

Screen readers expose these as a navigable list. A user can press a single key to jump from <nav> to <main>, skipping dozens of links. Without landmarks, they must tab through every single element.

Headings

Headings create a document outline that screen reader users rely on heavily. Follow these rules:

  • Use one <h1> per page — it is the page title.
  • Never skip levels — do not jump from <h2> to <h4>.
  • Use headings for structure, not styling — if you need bigger text, use CSS.
<!-- Correct heading hierarchy -->
<h1>Web Accessibility Course</h1>
  <h2>Module 1: Semantic HTML</h2>
    <h3>Landmarks</h3>
    <h3>Headings</h3>
  <h2>Module 2: ARIA</h2>
    <h3>Roles</h3>

Many screen reader users navigate by headings first. If your headings are vague or out of order, they cannot scan your page efficiently.

Forms

Accessible forms require labels. Every input must have an associated <label>:

<!-- Method 1: wrapping -->
<label>
  Email address
  <input type="email" name="email" />
</label>

<!-- Method 2: for/id association -->
<label for="password">Password</label>
<input type="password" id="password" name="password" />

Never use placeholder text as a substitute for labels. Placeholders disappear when the user starts typing, leaving them with no context.

Additional form best practices:

  • Group related fields with <fieldset> and <legend>
  • Use the correct type attribute (email, tel, url, number)
  • Provide clear error messages associated with the invalid field
<fieldset>
  <legend>Shipping Address</legend>
  <label for="street">Street</label>
  <input type="text" id="street" name="street" />
  <label for="city">City</label>
  <input type="text" id="city" name="city" />
</fieldset>

Lists

Use <ul>, <ol>, and <dl> for list content. Screen readers announce "list, 5 items" so users know what to expect:

<!-- Screen reader announces: "list, 3 items" -->
<ul>
  <li>Perceivable</li>
  <li>Operable</li>
  <li>Understandable</li>
</ul>

A series of <div> elements styled to look like a list provides no such context.

The First Rule

The first rule of accessible development: use native HTML elements whenever possible. Native elements come with built-in keyboard support, focus management, and screen reader semantics. Only reach for ARIA (covered in the next lesson) when no native element fits your needs.