Purpose
Tabs organize related content into panels, showing one panel at a time. Users select a tab to reveal the associated panel.
Usage Guidance
- Use tabs when content can be cleanly divided into named sections
- Ensure each tab label is concise and descriptive
- Avoid more than 7-8 tabs (use a different navigation pattern)
- Do not put critical information only in a single tab that might be hidden
Accessibility Considerations
- The tab container uses
role="tablist" - Each tab uses
role="tab"witharia-selectedandaria-controls - Each panel uses
role="tabpanel"witharia-labelledby - Only the active tab is in the tab order; inactive tabs use
tabindex="-1"
Keyboard Support
| Key | Action |
|---|---|
Tab |
Move focus into the tablist (to the selected tab) |
Arrow Right / Arrow Left |
Move to next/previous tab and select it (automatic activation) |
Home |
Move to and select the first tab |
End |
Move to and select the last tab |
Tab (within tablist) |
Move focus to the active panel |
Screen Reader Behavior
Screen readers announce “tab, 1 of 3, selected” (or not selected) for each tab. The tabpanel is announced as a region labeled by the active tab.
ARIA Requirements
role="tablist"on the containerrole="tab"on each tab buttonaria-selected="true|false"on each tabaria-controls="panel-id"on each tabtabindex="0"on selected tab;tabindex="-1"on othersrole="tabpanel"on each panelaria-labelledby="tab-id"on each panel
Common Mistakes
- Making all tabs focusable (should only be selected tab in tab order)
- Forgetting to update
aria-selectedwhen changing tabs - Using links instead of buttons for tabs
- Not providing keyboard arrow navigation between tabs
Live Example
Code Example
<div role="tablist" aria-label="Content sections">
<button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1" tabindex="0">Tab One</button>
<button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2" tabindex="-1">Tab Two</button>
<button role="tab" aria-selected="false" aria-controls="panel-3" id="tab-3" tabindex="-1">Tab Three</button>
</div>
<div id="panel-1" role="tabpanel" aria-labelledby="tab-1">Panel 1 content</div>
<div id="panel-2" role="tabpanel" aria-labelledby="tab-2" hidden>Panel 2 content</div>
<div id="panel-3" role="tabpanel" aria-labelledby="tab-3" hidden>Panel 3 content</div>
See main.js for the keyboard navigation implementation.