Semantic HTML for Accessibility
Use semantic HTML elements to convey document structure, meaning, and navigation landmarks to assistive technology
When to Use
- Building any user-facing web page or component
- Replacing
<div>and<span>soup with meaningful elements - Structuring page landmarks for screen reader navigation
- Ensuring heading hierarchy is logical and complete
- Reviewing existing markup for accessibility improvements
Instructions
- Use landmark elements to define page regions. Screen readers expose landmarks as a navigation menu, letting users jump directly to the section they need.
<header>Site branding and primary navigation</header>
<nav aria-label="Main">Primary navigation links</nav>
<main>Primary page content — exactly one per page</main>
<aside>Complementary content (sidebar, related links)</aside>
<footer>Site footer, legal links, copyright</footer>
- Use exactly one
<main>per page. - Use
aria-labelto distinguish multiple<nav>elements (e.g., "Main", "Footer", "Breadcrumb"). - Do not nest landmarks unnecessarily —
<nav>inside<header>is fine,<main>inside<main>is not.
- Use headings (
<h1>-<h6>) to create a logical outline. Headings are the primary way screen reader users scan a page. Follow a strict hierarchy — do not skip levels.
<h1>Product Catalog</h1>
<h2>Electronics</h2>
<h3>Laptops</h3>
<h3>Phones</h3>
<h2>Clothing</h2>
<h3>Men's</h3>
<h3>Women's</h3>
- One
<h1>per page (the page title). - Do not use headings for visual styling — use CSS classes instead.
- Do not skip from
<h2>to<h4>— screen readers announce heading levels.
- Use
<button>for actions and<a>for navigation. Buttons trigger in-page actions (submit, toggle, open modal). Links navigate to a URL. Do not use<div onclick>for either.
// Correct — button for action
<button Changes</button>
// Correct — link for navigation
<a href="/settings">Go to Settings</a>
// Wrong — div pretending to be interactive
<div className="btn">Save Changes</div>
Use
<ul>,<ol>, and<dl>for lists. Screen readers announce "list, 5 items" — giving users context about the content structure. Navigation menus should be<ul>inside<nav>.Use
<table>for tabular data, never for layout. Include<thead>,<th scope="col">, and<th scope="row">so screen readers can associate data cells with headers.
<table>
<caption>
Quarterly Sales
</caption>
<thead>
<tr>
<th scope="col">Region</th>
<th scope="col">Q1</th>
<th scope="col">Q2</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">North</th>
<td>$1.2M</td>
<td>$1.4M</td>
</tr>
</tbody>
</table>
Use
<form>,<fieldset>, and<legend>for form structure. Group related inputs with<fieldset>and provide a group label with<legend>.Use
<article>for self-contained content that makes sense independently (blog posts, comments, product cards). Use<section>for thematic grouping within a page — always pair<section>with a heading.Use
<time>for dates and durations to provide machine-readable time data.
<time datetime="2026-04-07">April 7, 2026</time>
- Use
<details>and<summary>for expandable content instead of custom JavaScript accordions. They are natively accessible with keyboard and screen reader support.
<details>
<summary>Order details</summary>
<p>Order #12345 — shipped on April 5, 2026.</p>
</details>
- Validate your HTML structure. Run the W3C validator and check the document outline. A well-structured document should make sense when read as a heading-only outline.
Details
Why semantic HTML matters: Assistive technology (screen readers, switch controls, voice navigation) relies on the HTML element type to determine how to present and interact with content. A <button> is announced as "button" and activated with Enter/Space. A <div> with an onClick is announced as "group" — the user has no idea it is interactive.
Implicit ARIA roles: Semantic elements carry implicit ARIA roles — <nav> is role="navigation", <main> is role="main", <button> is role="button". Using semantic HTML means you rarely need to add ARIA attributes manually.
Common anti-patterns:
<div class="header">instead of<header>- Using
<h3>because it looks the right size (use CSS for sizing) <a href="#"> — if it does not navigate, use<button><br>for spacing instead of CSS margin/padding<b>and<i>for styling — use<strong>and<em>for semantic emphasis, CSS for visual styling
Testing: Use the browser's accessibility tree inspector (Chrome DevTools > Accessibility tab) to see how your markup is exposed to assistive technology. The rendered accessibility tree should mirror the visual hierarchy.
Source
https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.