Accessible tabs (tablist)
Updated October 14, 2026 · 5 min read
Product pages often split description, specifications, delivery and reviews into tabs. Done right, tabs are quick to use with the keyboard. Done with div elements and click handlers, they hide most of the product information from keyboard and screen reader users. This page is part of the accessible UI patterns series.
When to use tabs
The APG defines tabs as "layered sections of content, known as tab panels, that display one panel of content at a time", where each panel has a tab that, when activated, displays it. Use tabs for a few related, parallel sections of similar weight that users switch between. Do not use them for:
- Navigation between pages — those are links in a
nav, even if styled as tabs; mark the current one witharia-current="page". - Long, sequential content or more than a handful of sections — use headings or an accordion.
Relevant WCAG criteria
- 4.1.2 Name, Role, Value (A): roles
tab,tablist,tabpaneland the selected state. - 1.3.1 Info and Relationships (A): the relationship between tab and panel is in the code.
- 2.1.1 Keyboard (A): all tabs can be reached and activated by keyboard.
- 2.4.3 Focus Order (A) and 2.4.7 Focus Visible (AA).
- 1.4.11 Non-text Contrast (AA): the selected-tab indicator needs 3:1 contrast.
- 1.4.1 Use of Color (A): the selected tab is shown by more than colour.
- 1.4.10 Reflow (AA): tabs still work on a 320 CSS pixels wide screen.
Code example
<div class="tabs">
<div role="tablist" aria-label="Product information">
<button type="button" role="tab" id="tab-desc" aria-selected="true"
aria-controls="panel-desc">Description</button>
<button type="button" role="tab" id="tab-specs" aria-selected="false"
aria-controls="panel-specs" tabindex="-1">Specifications</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-desc" aria-labelledby="tab-desc" tabindex="0">…</div>
<div role="tabpanel" id="panel-specs" aria-labelledby="tab-specs" tabindex="0" hidden>…</div>
<div role="tabpanel" id="panel-reviews" aria-labelledby="tab-reviews" tabindex="0" hidden>…</div>
</div>
What the script must do:
- Arrow keys move focus between tabs. This uses a roving tabindex: the active tab has
tabindex="0", the otherstabindex="-1", as described in the APG keyboard guide. - On activation: set
aria-selected="true"on the new tab andfalseon all others, show its panel and hide the rest withhidden. - The
tablisthasaria-label, oraria-labelledbyif there is a visible heading. - The APG says a panel "should set
tabindex="0"" when it has no focusable content or its first content is not focusable, so Tab can reach it. - A vertical tab list gets
aria-orientation="vertical"and uses Up and Down Arrow.
Keyboard interaction
From the APG tabs pattern (horizontal tab list):
| Key | Function |
|---|---|
| Tab | Moves focus into the tab list onto the active tab; from the list, to the panel or the next element |
| Left Arrow | Previous tab; from the first, wraps to the last. Optionally activates it |
| Right Arrow | Next tab; from the last, wraps to the first. Optionally activates it |
| Space or Enter | Activates the tab if it was not activated on focus |
| Home / End | Optional: first or last tab |
| Delete | Optional: closes a tab, if deletion is allowed |
Automatic vs manual activation. The APG says "it is recommended that tabs activate automatically when they receive focus" if the panel is displayed without noticeable latency, which usually means its content is already loaded. If showing a panel needs a network request, automatic activation makes arrow navigation slow — then use manual activation with Space or Enter. The APG has examples of both.
Common mistakes on online shops
- Tabs built as
liordivelements with click handlers: no role, no keyboard, no selected state. - All tabs in the tab sequence and no arrow keys — or arrow keys, but
role="tab"missing so screen readers do not announce "tab 2 of 3". aria-selectedstaystrueon the first tab after another one is chosen.- Panels hidden with
opacity: 0or moved off-screen but still readable and focusable. - Navigation styled as tabs with
role="tab"while each "tab" loads a new page. - Reviews tab loaded by script and automatic activation that fires a request on every arrow key press.
- The selected tab shown only by a slightly different colour.
What automated checks catch vs manual testing
| Automated (axe-core rule) | What it finds |
|---|---|
aria-required-parent |
role="tab" that is not inside a tablist |
aria-required-children |
role="tablist" without tab children |
aria-valid-attr-value |
aria-controls/aria-labelledby pointing to missing IDs; invalid aria-selected |
aria-allowed-attr |
Attributes that are not allowed on tab or tabpanel |
button-name, aria-command-name |
Tabs without a name, for example icon-only tabs |
duplicate-id-aria |
Duplicate IDs used by ARIA references |
scrollable-region-focusable |
Scrollable panels that keyboard users cannot reach |
All are cards in our rule library. Manual testing: Tab into the tab list, use the arrow keys, Home and End, check that only one tab is in the tab sequence, that the panel changes and that a screen reader announces the role, position and selected state. Check the visual indicator with the contrast checker.
Run the free one-page check on a product page. It is an automated check, not a full audit.
Frequently asked questions
Which ARIA roles do accessible tabs need?
A container with role="tablist" and a label, elements with role="tab" inside it, each with aria-selected and aria-controls, and panels with role="tabpanel" labelled by their tab.
How do keyboard users move between tabs?
Tab moves into the tab list onto the active tab; Left and Right Arrow move between tabs, wrapping at the ends; Home and End are optional; Tab again moves on to the panel. Only one tab is in the tab sequence.
Should a tab activate on focus or on Enter?
The APG recommends that tabs activate automatically when they receive focus, as long as the panel appears without noticeable delay. If the panel has to load first, use manual activation with Enter or Space.
Are tabs or an accordion better on a mobile product page?
Both can be accessible. Tabs need horizontal space and the full keyboard model; an accordion of disclosure buttons is simpler and works well on narrow screens. Many shops use tabs on desktop and an accordion on mobile.
Can an automated check test tabs?
It finds tab roles outside a tablist, tablists without tabs, aria-controls pointing to missing IDs and invalid aria-selected values. It cannot check arrow keys or whether aria-selected changes when another tab is chosen.
Sources
- W3C WAI, APG Tabs pattern: https://www.w3.org/WAI/ARIA/apg/patterns/tabs/
- W3C WAI, APG Developing a Keyboard Interface (roving tabindex): https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/