A tab interface allows users to switch between panels of related content using
a row of tab controls. When implemented accessibly, tabs are fully keyboard
operable, correctly announced by screen readers, and maintain a logical focus
and selection state.
[1]
A tab interface requires three ARIA roles applied to the correct elements:
| Role | Applied to | Purpose |
|---|---|---|
| tablist | The container wrapping all tabs | Groups the tabs together |
| tab | Each individual tab button | Identifies it as a tab control |
| tabpanel | Each content panel | Associates the panel with its tab |
| [1] |
On each tab:
On each tabpanel:
The tab interface uses arrow key navigation inside the tablist — not Tab.
This is the most commonly misunderstood aspect of the pattern.
| Key | Action |
|---|---|
| Tab | Moves focus into the tablist (to the active tab), then out to the tabpanel |
| Left / Right arrow | Moves focus between tabs |
| Home | Moves focus to the first tab |
| End | Moves focus to the last tab |
| Enter / Space | Activates the focused tab (if not using automatic activation) |
Automatic activation: The tab panel changes as the user arrows between
tabs. Focus movement triggers selection. Simpler to implement and preferred
for most use cases.
Manual activation: The user must press Enter or Space to activate a tab
after arrowing to it. Useful when tab panels are slow to load.
[3]
Using Tab key to move between tabs. This forces users to Tab through every
tab to reach the panel. Use arrow keys within the tablist instead.
Missing aria-selected. Without aria-selected, screen reader users cannot
tell which tab is active.
Hiding inactive panels with display: none. This is correct — inactive
panels should be hidden from all users including screen readers. Do not use
visibility: hidden or opacity: 0 alone, as these leave the content in the
accessibility tree.
Last edited Apr 5, 2026, 7:20 PM · P**** J****