← Back to home

Without semantic structure, keyboard navigation for screen readers simply fails.

Updated

Screen readers don't navigate pages the way sighted users do. They rely on a map built from semantic elements: headings, landmarks, buttons and links.

When that map exists, keyboard shortcuts make navigation fast:

  • H jumps between headings
  • B jumps between buttons
  • F jumps between form fields
  • L jumps between lists

These shortcuts only work if the elements underneath are semantically correct.

Light beige background with a large italic headline stating that without semantic structure, keyboard navigation for screen readers simply fails. The body explains that screen readers rely on a map built from semantic elements, and that shortcuts like H for headings and B for buttons only work when the correct HTML elements are present. A highlighted indigo block closes with: when a page uses only div and span, the user lands on a blank map and must navigate every element one by one.

What the wrong structure looks like

Consider a navigation menu built entirely with <div> and <span>:

<!-- No semantic structure — screen reader sees anonymous boxes -->
<div class="nav">
  <span onclick="navigate('/home')">Home</span>
  <span onclick="navigate('/about')">About</span>
  <span onclick="navigate('/contact')">Contact</span>
</div>

A screen reader user pressing L to jump to the navigation finds nothing. Pressing Tab to reach the links also finds nothing, because <span> elements aren't focusable by default. The user has to read through every element on the page in order.

Compare that with the semantic version:

<!-- Semantic structure — screen reader announces "navigation" landmark -->
<nav aria-label="Main navigation">
  <a href="/home">Home</a>
  <a href="/about">About</a>
  <a href="/contact">Contact</a>
</nav>

The browser announces the landmark and the user can jump straight to it. The links are natively focusable and announced correctly.

Headings are your page outline

Screen reader users often navigate by headings first to get an overview of the page before reading the content, much like sighted users scan visually.

<!-- Wrong — styled text that looks like a heading but isn't one -->
<div class="heading-xl">Getting started</div>
<div class="heading-lg">Installation</div>
<div class="heading-lg">Configuration</div>

<!-- Right — a real heading hierarchy the screen reader can announce -->
<h1>Getting started</h1>
<h2>Installation</h2>
<h2>Configuration</h2>

With the first example, pressing H finds nothing. With the second, the user gets the full document outline in seconds.

Buttons that aren't buttons

Interactive elements built on non-interactive HTML are a common source of keyboard failures:

<!-- Wrong — div has no keyboard role, not focusable, not announced as button -->
<div class="btn" onclick="submitForm()">Submit</div>

<!-- Right — natively focusable, announced as button, activatable with Space and Enter -->
<button type="button" onclick="submitForm()">Submit</button>

When a <div> stands in for a <button>, keyboard users can't reach it at all unless someone adds tabindex and role="button" by hand, and even then the Space and Enter handlers have to be written manually. The native element gives you all of this for free.

The cost

For someone navigating only by keyboard or screen reader, a page without semantic structure can take much longer to use, or become impossible to navigate.

The fix is almost always simpler than the workaround. Using <nav>, <main>, <button> and <h1> for their intended purpose creates the map, with no ARIA and no extra JavaScript. For screen reader users, that decides whether the page works at all.

LinkedInX