⚠️ Design system CSS not found. Check the path in cms/docs.config.js → designSystemPath, then re-run npm run docgen.

Tabs

Switch between related content without leaving the page

Design System / Tabs
Download .md file
Open .md in new tab

Tabs organise content into panels that the user switches between. The component requires JavaScript (assets/js/tabs.js) for interaction and follows the WAI-ARIA tabs pattern.


Basic usage

Panel 1 content

Panel 2 content

Panel 3 content

<div class="tabs" role="tablist" aria-label="Section name">
  <button class="tab is-active" role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1">Tab One</button>
  <button class="tab" role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2">Tab Two</button>
  <button class="tab" role="tab" aria-selected="false" aria-controls="panel-3" id="tab-3">Tab Three</button>
</div>

<div class="tab-panel" id="panel-1" role="tabpanel" aria-labelledby="tab-1">
  Panel 1 content
</div>
<div class="tab-panel is-hidden" id="panel-2" role="tabpanel" aria-labelledby="tab-2">
  Panel 2 content
</div>
<div class="tab-panel is-hidden" id="panel-3" role="tabpanel" aria-labelledby="tab-3">
  Panel 3 content
</div>

JavaScript

Include assets/js/tabs.js on any page that uses tabs. The script automatically initialises all [role="tablist"] elements on the page.

<script src="/assets/js/tabs.js"></script>

No manual initialisation is required.


Keyboard interactions

Key Action
Tab Moves focus to the active tab, then to the panel
ArrowRight Moves focus to the next tab
ArrowLeft Moves focus to the previous tab
Home Moves focus to the first tab
End Moves focus to the last tab
Enter / Space Activates the focused tab (via click)

Accessibility

  • The tab list uses role="tablist" with a descriptive aria-label
  • Each tab uses role="tab" with aria-selected and aria-controls
  • Each panel uses role="tabpanel" with aria-labelledby
  • Hidden panels use (display: none) so they are removed from the tab order
  • Focus ring appears on focus-visible

Usage rules

Do:

  • Use unique IDs for tabs and panels on each page
  • Set one tab as is-active and aria-selected="true" by default
  • Provide a descriptive aria-label on the tablist

Don't:

  • Don't use tabs for sequential steps (use a stepper pattern instead)
  • Don't nest tablists inside tab panels

CSS reference

This section documents how the component is built. For usage, see the sections above.

Tokens

Token Default What it controls
Active tab text colour
Inactive tab text colour
Bottom border indicator

Selectors

Selector Purpose
Tab list container — flex row, bottom border
Individual tab button — padding, colour, cursor
.tab:hover Tab hover — text colour change
.tab.is-active Active tab — active colour, bold weight
.tab.is-active::after Active indicator — bottom border pseudo-element
.tab:focus-visible Tab focus ring
Panel content container — padding
a.tab Link-as-tab variant — text-decoration reset
a.tab:hover Link tab hover
On this page
  • Basic usage
  • JavaScript
  • Keyboard interactions
  • Accessibility
  • Usage rules
  • CSS reference
Previous

Book Cover

Next

Accordion

Was this page helpful?

We use this feedback to improve our documentation.

Thanks for your feedback

Send feedback

© 2026 By Default