Skip to content
easeweb
Search topics

Tabs that only work with a mouse

Product tabs are list items with click handlers, so they take no keyboard focus and say nothing about which panel is shown.

WCAG 2.2
SC 4.1.2ASC 2.1.1A
Required by
Section 508 · EN 301 549 (EU)
Broken <li class="tab active" onclick="show('description')">
The accessibility problem illustrated: Tab jumps past the tabs. None says it is shown.
01

The problem

Keyboard users can't open any tab but the first, and screen reader users aren't told that the tabs switch content or which one is shown.

02

Try it

Open the Sizes tab with the keyboard.

Press Tab, then try the arrow keys, Home and End. The panel shows what a screen reader says. Does it say which tab is shown?

Broken Can you fix this?

  • Description
  • Sizes
  • Reviews (12)

Waxed cotton, lined with wool. Care instructions

Screen reader says:

(Press Tab)

A recreated demo. The broken version is intentionally inaccessible.

03

The fix

Build the tabs pattern on buttons: one Tab stop, the arrow keys, and aria-selected on the shown tab.

  1. 1Give the tab list one Tab stop, and move between tabs with the arrow keys, Home and End.
  2. 2Mark the shown tab with aria-selected="true", and draw its look from that attribute.
  3. 3Hide the other panels with hidden, and keep them in the page.
Before List items with click handlers
<ul class="tabs">  <li class="tab active" onclick="show('description')">Description</li>  <li class="tab" onclick="show('sizes')">Sizes</li>  <li class="tab" onclick="show('reviews')">Reviews (12)</li></ul><div class="panel" id="description">  <p>Waxed cotton, lined with wool. <a href="/care">Care instructions</a></p></div><div class="panel" id="sizes" style="display: none">…</div><div class="panel" id="reviews" style="display: none">…</div>
After The tabs pattern on buttons
<div role="tablist" aria-label="Product details">  <button type="button" role="tab" id="tab-description"          aria-selected="true" aria-controls="panel-description">Description</button>  <button type="button" role="tab" id="tab-sizes"          aria-selected="false" aria-controls="panel-sizes" tabindex="-1">Sizes</button>  <button type="button" role="tab" id="tab-reviews"          aria-selected="false" aria-controls="panel-reviews" tabindex="-1">Reviews (12)</button></div><div role="tabpanel" id="panel-description" aria-labelledby="tab-description" tabindex="0">  <p>Waxed cotton, lined with wool. <a href="/care">Care instructions</a></p></div><div role="tabpanel" id="panel-sizes" aria-labelledby="tab-sizes" tabindex="0" hidden>…</div><div role="tabpanel" id="panel-reviews" aria-labelledby="tab-reviews" tabindex="0" hidden>…</div>

Fixing this with an AI coding assistant? Get this guide as Markdown

04

Verify the fix

5 checks, no mouse.

Test with: Keyboard, Screen reader, Zoom, Forced colors

0 of 5 checked

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the shared tabs component changes.

Limits

This is a starting pattern, not a guarantee for every application. The script is a minimal sketch: it handles one tab list per page, and has no deep links or remembered selection. Screen readers word tabs and their position differently. Test the complete journey with your target assistive technology.

This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.

Keep this fixed as your code changes.

Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.

How retests work