Tabs
The .c-tabs component renders a [role="tablist"] of [role="tab"] buttons
that switch between [role="tabpanel"]s. The active state is APP state: set
aria-selected="true" on the tab and [hidden] on inactive panels.
When to use
- Settings pages with grouped sections.
- Dashboards switching between data views.
- Master-detail regions with a small fixed set of tabs.
Semantic HTML
<div class="c-tabs">
<div class="c-tabs__list" role="tablist" aria-label="Sections">
<button
class="c-tabs__tab"
role="tab"
aria-selected="true"
id="tab-overview"
aria-controls="panel-overview"
tabindex="0"
>
Overview
</button>
<button
class="c-tabs__tab"
role="tab"
aria-selected="false"
id="tab-settings"
aria-controls="panel-settings"
tabindex="-1"
>
Settings
</button>
</div>
<div
class="c-tabs__panel"
role="tabpanel"
id="panel-overview"
aria-labelledby="tab-overview"
>
<p>Active panel.</p>
</div>
<div
class="c-tabs__panel"
role="tabpanel"
id="panel-settings"
aria-labelledby="tab-settings"
hidden
>
<p>Hidden panel.</p>
</div>
</div>
Class contract
| Selector | Role |
|---|---|
.c-tabs | Wrapper - provides grid + gap. |
.c-tabs__list | The [role="tablist"] container. |
.c-tabs__tab | A tab button ([role="tab"]). |
.c-tabs__count | Optional count chip inside a tab. |
.c-tabs__panel | A panel ([role="tabpanel"]). Inactive ones carry [hidden]. |
Tokens consumed
--pl-color-{accent,surface,surface-2,text,text-muted,border},
--pl-space-{1,2,3}, --pl-text-{xs,sm}, --pl-duration-1, --pl-ease-standard,
--pl-radius-{sm,pill}.
Accessibility
- Keyboard: implement roving tabindex (arrow keys move between tabs,
Home/End jump to first/last). The framework sets
tabindexvalues in the preview; your app must update them on arrow-key navigation. - Focus-visible:
:focus-visibledraws a--pl-focus-colorring. - Selected indicator: box-shadow on the block-end edge (never shifts layout). Selected tab gets accent color + bolder weight.