A11y Patterns
All patterns

Tabs

A pattern for dividing content into tabbed sections and switching between them

Related WCAG criteria — click to view details

Code example

Baseline (React)tsx
Loading...

Common baseline

Applies to all design systems
Must6
  • tablist role on the tab container

    The element wrapping all tabs must have role="tablist".

  • tab role on each tab

    Each tab element must have role="tab".

  • tabpanel role on each panel

    Each content section must have role="tabpanel" and a unique id.

  • Tab references its panel via aria-controls

    Each tab must have aria-controls pointing to the id of its panel.

  • Active tab has aria-selected

    The active tab must have aria-selected="true"; all others must have aria-selected="false".

  • Arrow key navigation between tabs

    Left/right arrow keys navigate between tabs; Tab moves to the active panel.

Should3
  • Panel is labeled by its tab

    Each tabpanel should reference its controlling tab via aria-labelledby.

  • Use roving tabindex

    Only the active tab should have tabindex="0"; inactive tabs should have tabindex="-1".

  • Home/End keys for first/last tab

    Home should jump to the first tab; End should jump to the last.

Avoid2
  • Do not omit ARIA roles

    Implementing tabs with only CSS and JS without ARIA roles makes them invisible to screen readers.

  • Do not expose inactive panels

    Inactive tabpanels must be hidden using the hidden attribute or display:none.

Design system implementations

Additional checks

  • Connect TabPanel and Tabs by value

    Match the value of MUI Tabs and each TabPanel to control the active panel.

  • Add aria-label or aria-labelledby

    Add aria-label or aria-labelledby to the MUI Tabs component.

Code sample

MUI Tabstsx
Loading...

Implementation notes

  • MUI Tabs automatically handles arrow key navigation and roving tabindex.
  • If TabScrollButton is visible, guide screen reader users on the scroll direction.

References