Skip to main content
Cayuse Design System Lato · 4pt grid · WCAG 2.1 AA

Components · Navigation

Tabs

Switch between panels of related content inside one view, without leaving the page. Each panel is a peer of the others — tabs are not a sequence.

Figma source: Tabs ↗

Examples

Tabs — click, or focus one and use the arrow keys

Overview

Longitudinal study of soil microbiota. Submitted to the National Science Foundation on 14 March 2026.

html
<div class="cds-tabs" role="tablist" aria-label="Proposal sections">
  <button type="button" class="cds-tab" role="tab" id="tab-1"
          aria-controls="panel-1" aria-selected="true">Overview</button>
  <button type="button" class="cds-tab" role="tab" id="tab-2"
          aria-controls="panel-2" aria-selected="false" tabindex="-1">Budget</button>
</div>

<div class="cds-tabpanel" role="tabpanel" id="panel-1" aria-labelledby="tab-1">…</div>
<div class="cds-tabpanel" role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>…</div>

Figma properties

PropertyValuesNotes
ActiveOn · OffWhether this tab’s panel is showing.
FocusOn · OffKeyboard focus.
Tab TexttextThe tab label.

Usage

The Typography page notes that a panel’s heading uses the Section Heading style — tabs divide a view into sections, and each panel should carry its own <h2>.

When to use it

  • Use for peer views of one subject, where the user moves between them freely.
  • Keep labels to one or two words so the row fits without wrapping.
  • Give each panel a heading matching its tab.
  • Preserve the selected tab when the user navigates away and returns, if the choice is meaningful.

When not to use it

  • Do not use for a sequence with an order — use form sections with Previous/Next.
  • Do not hide required form fields behind an unselected tab; a user can submit without ever seeing them.
  • Do not nest tabs inside tabs.
  • Do not use more tabs than fit on one line at 1440px — that is a sign the view is doing too much.
Validation across tabs

If a form is split across tabs and a hidden panel fails validation, the user presses Submit and nothing visible happens. Two things are required: mark the tab itself as containing errors, and move focus to the first failing field — switching tabs as part of doing so. See the Inputs pattern.

Accessibility

  • The tab row is a single tab stop. Tab moves into the selected tab; Left and Right arrows move between tabs; Home and End jump to the ends. Tab again moves into the panel.
  • Wire role="tablist" / role="tab" / role="tabpanel", with aria-controls and aria-labelledby pairing each tab to its panel.
  • Only the selected tab has tabindex="0"; the rest are -1.
  • Hide inactive panels with the hidden attribute so their content is out of the accessibility tree, not just invisible.
  • The active indicator is a 3px underline as well as a colour change — colour alone would fail SC 1.4.1.

Tokens consumed

TokenApplied toResolves to
--tab-active-textSelected label--primary-brand-color
--tab-active-border3px underline--primary-brand-color
--tab-inactive-textUnselected label--color-black
--tab-borderRow baseline--color-gray-300