Styles live in scss/components/_tab.scss. Tabbed sections switch panels with keyboard support and WAI-ARIA tab semantics.
Anatomy
| Part | Class | Role |
|---|---|---|
| Bar | .tabs | Column stack: list + separator + panels |
| List | .tabs__list | Flex row of tab buttons (role="tablist") |
| Separator | .tabs__separator | Full-width rule under the list |
| Item | .tab | role="tab", bottom indicator when selected |
| Icon | .tab__icon | Optional 20px icon (aria-hidden) |
| Label | .tab__label | Visible tab text |
| Panel | .tab-panel | role="tabpanel", linked via aria-labelledby |
Prerequisites
- PimentCSS installed, Installation.
- Icons, optional tab icons via
ph()(Phosphor in this doc). - Typography, labels use body medium tokens (Typography).
Tab item states
Matrix previews are static buttons (no tablist roles) so they do not compete with live tablists. Doc-only .tab--hover and .tab--focus preview states; production uses :hover and :focus-visible. Selected pairs with .tab--selected or aria-selected="true".
Tab bar (static)
Text-only tabs with one visible panel. The selected tab uses tabindex="0"; others use -1 until focus moves in a live bar.
Content for General. Link panels with aria-controls and aria-labelledby.
Content for Details. Link panels with aria-controls and aria-labelledby.
Content for History. Link panels with aria-controls and aria-labelledby.
Settings panel (placeholder).
<div class="tabs">
<div class="tabs__list" role="tablist" aria-label="Sections"><button type="button" class="tab" role="tab" id="tab-a" aria-selected="false" aria-controls="panel-a" tabindex="-1">
<span class="tab__label">General</span>
</button><button type="button" class="tab tab--selected" role="tab" id="tab-b" aria-selected="true" aria-controls="panel-b" tabindex="0">
<span class="tab__label">Details</span>
</button></div>
<hr class="tabs__separator" />
<div id="panel-b" class="tab-panel" role="tabpanel" aria-labelledby="tab-b" tabindex="0">…</div>
</div>
Tab bar with icons
Icons are decorative; keep aria-hidden="true" on the icon element and put the name in .tab__label.
Content for General. Link panels with aria-controls and aria-labelledby.
Content for Details. Link panels with aria-controls and aria-labelledby.
Content for History. Link panels with aria-controls and aria-labelledby.
Settings panel (placeholder).
Interactive tab bar
Add data-tabs-live on .tabs and call wireAllTabs() after load. Arrow Left/Right (and Up/Down), Home, End, and click update selection and panels.
// See docs-site/src/lib/tabs-behavior.ts (tablist selection, panels, arrow keys, Home/End).
Overview: summary cards and recent activity.
Billing: invoices and payment methods.
Team: members and roles.
Security panel (disabled tab cannot be opened).
Class reference
| Class | Description |
|---|---|
.tabs | Tab bar container (column, full width) |
.tabs__list | Horizontal flex list of tabs |
.tabs__separator | Border-top rule under the list |
.tab | Tab button: min-height 50px, bottom indicator |
.tab--selected | Selected tab (semibold, action border) |
.tab--hover | Doc-only hover preview |
.tab--focus | Doc-only focus ring preview |
.tab--disabled | Doc-only disabled preview (prefer disabled) |
.tab__icon | 20px icon slot |
.tab__label | Tab label text |
.tab-panel | Panel content; use hidden when inactive |
Customize (Sass)
-
Tab sizing
Override padding, list gap, indicator width, and min height before importing components.@use "pimentcss-design-system" with ( $tab-item-px: 1rem, $tab-item-py: 0.75rem, $tab-list-gap: 0.75rem, $tab-min-height: 3.125rem, $tab-indicator-width: 0.25rem ); -
Rebuild CSS
Run after editing _tab.scss.npm run build:css
Accessibility (RGAA / WCAG)
Tablist pattern
- Roles,
role="tablist"on the list container,role="tab"on each tab,role="tabpanel"on each panel. - Selection, set
aria-selected="true"on the active tab only; pair with.tab--selectedfor visuals. - Linkage, each tab needs a unique
id,aria-controlspointing to its panelid, and panels usearia-labelledbyback to the tab. - Roving tabindex, active tab
tabindex="0", others-1; move focus with arrow keys in the live example. - Panels, hide inactive panels with the
hiddenattribute (and optionallyaria-hidden="true"when wired). - Disabled, use the native
disabledattribute on tab buttons. - Keyboard, Arrow Left/Right (and Up/Down), Home, End on the live tab bar; Enter/Space activate on click.
- Focus,
:focus-visibleoutline is built into.tab.