Accessibility
a11y/tabs-keyboard
A tab list is one Tab stop; Left and Right Arrow (Up and Down when vertical), Home and End move between tabs.
seriousmanualWCAG 2.1.1 · Afe-a11y-tabs-accordion
Why
Screen reader users who hear "tab list" press the arrow keys, because that is what the role promises. If every tab is a separate Tab stop and arrows do nothing, the widget behaves unlike its announcement and keyboard users tab through every tab to reach the panel.
Fix
Roving tabindex: the selected tab has tabindex="0", the others -1. Arrow keys move focus (and select, in automatic activation) with wrapping; Home and End go to the first and last tab; Tab moves into the panel. Use manual activation (Enter or Space selects) when showing a panel is slow. Set aria-orientation="vertical" for a vertical list.
Examples
tablist.addEventListener('keydown', (e) => {
const next = { ArrowRight: i + 1, ArrowLeft: i - 1, Home: 0, End: tabs.length - 1 }[e.key]
if (next === undefined) return
e.preventDefault()
select((next + tabs.length) % tabs.length)
})Sources
Facts
- Id
a11y/tabs-keyboard- Severity
- serious
- Check
- manual a person reviews it; the report lists it as a checklist
- Applies to
page- WCAG 2.2
- 2.1.1, level A
- Same problem in
- axe-core
aria-required-children, axe-corearia-required-parent - Taught by the skill
fe-a11y-tabs-accordionTabs and accordions- Since version
- 0.1.0
Read it in the terminal
npx github:dawidolko/frontend-skills explain a11y/tabs-keyboard