Tabs
Tab strip that shows one content panel at a time.
c2-tabs
Tab strip that shows one content panel at a time.
Light-DOM children are split in two groups: every <c2-tab for="…"> becomes a tab in the header,
every other child is a panel whose id matches a tab's for. Only the panel of the selected tab is
rendered. The header is a tablist: Arrow keys, Home and End move between tabs, Enter and Space
activate the focused one.
The strip assigns its children to its slots itself (manual slot assignment), so neither the tabs nor the
panels need a slot attribute and none is written on them; a slot="tab" already in the markup is
harmless. When the shadow root was server-rendered (declarative shadow DOM, which has no manual mode)
the strip falls back to writing slot on the tabs and the selected panel. The selected tab matches
c2-tab:state(selected). Panels without a role get role="tabpanel" and aria-labelledby (and the
tab an id for it): a plain element has no ElementInternals, so write those yourself in
server-rendered markup and nothing is added.
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
aria-label | string | null | null | Accessible name for the tab list. |
selected-tab | string | — | for value of the selected tab (and id of the visible panel). Falls back to the first enabled tab. |
Slots
| Name | Description |
|---|---|
tab | The <c2-tab> children (assigned by the strip; no slot attribute needed). |
tab-content | The panel of the selected tab (assigned by the strip from the child whose id matches selected-tab; no slot attribute needed). |
Events
| Name | Type | Description |
|---|---|---|
selection-change | CustomEvent<TabsSelectionChangeEventDetail> | Fired after the user selects another tab. detail.value is the new selected-tab. Not fired for programmatic changes. Does not bubble: several components fire selection-change, so a listener belongs on the element itself rather than on an ancestor. The name matches c2-list, c2-select and c2-table; it is deliberately not change, which every native form control bubbles — a c2-text-field inside a panel would otherwise reach a listener meant for the tab strip. |
CSS custom properties
Grouped by semantic target and state from --c2-<component>__<target>__<state>--<property>. Click a group to collapse it; click a name to copy it.
| Name | Type | Default | Description |
|---|---|---|---|
--c2-tabs--box-shadow | box-shadow | inset 0px -2px 0px 0px rgb(213, 213, 213) | |
--c2-tabs--justify-content | justify-content | flex-start | |
--c2-tabs--background-color | background-color | — | |
--c2-tabs--height | pixel | — | |
--c2-tabs--gap | pixel | — | |
--c2-tabs--border-radius | border-radius | — | |
--c2-tabs--padding-top | padding | — | |
--c2-tabs--padding-right | padding | — | |
--c2-tabs--padding-bottom | padding | var(--c2-tabs__indicator--height) | |
--c2-tabs--padding-left | padding | — | |
--c2-tabs__tab--gap | pixel | 8px | Space between an icon and the label inside a tab. |
--c2-tabs__tab--flex | flex | — | Set 1 1 0 to make every tab grow to the same width. |
--c2-tabs__tab--justify-content | justify-content | center | |
--c2-tabs__tab--font-weight | font-weight | — | |
--c2-tabs__tab--font-size | font-size | — | |
--c2-tabs__tab--font-style | font-style | — | |
--c2-tabs__tab--font-family | font-family | — | |
--c2-tabs__tab--padding-top | padding | 8px | |
--c2-tabs__tab--padding-right | padding | 16px | |
--c2-tabs__tab--padding-bottom | padding | 8px | |
--c2-tabs__tab--padding-left | padding | 16px | |
--c2-tabs__tab--color | color | — | |
--c2-tabs__tab--background-color | background-color | — | |
--c2-tabs__tab--border-top-left-radius | border-radius | — | |
--c2-tabs__tab--border-top-right-radius | border-radius | — | |
--c2-tabs__tab--border-bottom-left-radius | border-radius | — | |
--c2-tabs__tab--border-bottom-right-radius | border-radius | — | |
--c2-tabs__tab__hover--color | color | rgb(2, 101, 220) | |
--c2-tabs__tab__hover--background-color | background-color | — | |
--c2-tabs__tab__selected--color | color | rgb(2, 101, 220) | |
--c2-tabs__tab__selected--background-color | background-color | — | |
--c2-tabs__tab__focus--outline | outline | 2px solid rgba(2, 101, 220, 0.4) | |
--c2-tabs__tab__focus--outline-offset | pixel | -2px | |
--c2-tabs__tab__disabled--opacity | opacity | 0.38 | |
--c2-tabs__indicator--color | color | rgb(109, 109, 109) | |
--c2-tabs__indicator--border-radius | border-radius | — | |
--c2-tabs__indicator--height | pixel | 2px | |
--c2-tabs__indicator--bottom | pixel | 0px | |
c2-tab
A single tab inside <c2-tabs>. Its for attribute names the id of the panel it controls.
The parent owns selection: it sets selected and the roving tabindex; this element exposes
them as role="tab", aria-selected, aria-controls and aria-disabled through ElementInternals, so no host attribute is written.
The selected tab matches c2-tab:state(selected).
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
label | string | — | Text label, used when no content is slotted. Reflected so SSR keeps it as an attribute. |
for | string | — | id of the panel this tab controls. |
disabled | boolean | false | Prevents activation and removes this tab from keyboard navigation. |
selected | boolean | false | Set by the parent <c2-tabs>; do not set by hand. Not reflected: the strip selects a tab while the page upgrades,
before a framework hydrates, so it is exposed as the custom state c2-tab:state(selected) instead. |
Slots
| Name | Description |
|---|---|
(default) | Tab label. Defaults to the label attribute. |
Events
| Name | Type | Description |
|---|---|---|
tab-change | CustomEvent<string> | Fired when the user activates this tab (click, Enter or Space). detail is the for value. Cancelable: preventDefault() keeps the current tab. |