Checklist
Updated: 2026-09-10
1) Semantics & relationships
- Wrap the set of tabs in
role="tablist"with a usefularia-label. - Each tab is
role="tab". The selected tab hasaria-selected="true". - Each panel is
role="tabpanel". - Link each tab to its panel with
aria-controlson the tab. - Link each panel back to its tab with
aria-labelledbyon the panel.
2) Focus model (roving tabindex)
- Only one tab should be in the normal tab order: selected tab has
tabindex="0"; all other tabs havetabindex="-1". - Tab should move focus from the selected tab into the active panel’s interactive elements.
- Don’t put the whole tablist in the tab order as a single element (it blocks discovery of individual tabs).
3) Keyboard interactions
- Horizontal tablists: ←/→ move focus to previous/next tab (wrap optional but common).
- Vertical tablists: ↑/↓ move focus to previous/next tab.
- Home/End jump focus to first/last tab.
- Enter/Space activates the focused tab in manual activation mode.
4) Activation mode (manual vs automatic)
- Manual activation: arrow keys move focus only; selection/panel changes on Enter/Space.
- Automatic activation: selection/panel changes immediately as focus moves.
- If panels are expensive to load (network calls, big re-render), prefer manual activation.
5) Panel visibility
- Hide inactive panels with the
hiddenattribute (or equivalent) so they’re removed from the accessibility tree and can’t be tabbed into. - Avoid “CSS-only hiding” that leaves interactive elements focusable (ghost focus).
6) Announcement & state
- Keep
aria-selectedaccurate at all times. - Don’t use
role="tab"with nested interactive elements (tabs should behave like single controls). - Optional: add a small
role="status"message when selection changes (useful in some UIs).
7) Common failure modes (quick sniff test)
- If arrow keys do nothing, it’s probably not a real tabs pattern.
- If Tab moves through every tab, you probably forgot roving tabindex.
- If a screen reader doesn’t announce “tab / selected”, you may be missing roles and
aria-selected. - If you can tab into a hidden panel, your hiding strategy is wrong.
Try the interactive micro-demo: Tabs demo.