On this page
Proposed CSC Standards · 0.1.0
Tabs
Switch a panel inside the same page.
Show one of a few peer panels without leaving the page.
What this describes
When to use
- Two to six peer views of the same subject.
- The person should keep the surrounding page chrome.
When not to use
- Destinations in the information architecture. Use TopNav or Sidebar.
- A long sequential process. Use Stepper.
Allowed variants
Underline
Page-level panels.
- Hierarchy
- Text with an underline on the selected tab.
- Use in
- Document sections.
- Restriction
- Selection is not color alone.
- Accessibility
- aria-selected plus the underline.
- Responsive
- Wraps.
Pills
A smaller set of filters.
- Hierarchy
- Filled selected pill.
- Use in
- Short labels.
- Restriction
- Keep labels to one or two words.
- Accessibility
- Selected state includes text or aria-selected.
- Responsive
- Wraps onto a second line.
Segmented
Two or three exclusive views.
- Hierarchy
- Joined control.
- Use in
- Binary or ternary choices.
- Restriction
- Do not use it for more than four items.
- Accessibility
- Same tab semantics.
- Responsive
- The segment can be full width. Each segment stays at least 24 CSS pixels tall.
Boxed
Tabs that need a container.
- Hierarchy
- Bordered list.
- Use in
- Cards.
- Restriction
- One tablist.
- Accessibility
- Same roles.
- Responsive
- The box stays inside the card.
Mandatory rules
Use the tab pattern, not a row of buttons that swap hidden divs without roles
Tabs expose tablist, tab, and tabpanel, with arrow-key movement between tabs.
Implementation detail
The APG tabs pattern is what assistive technology expects. The CSC Tabs component is built on Radix Tabs.
Use tablist, tab, and tabpanel, and move between tabs with arrow keys.
Check: Arrow keys move between tabs. The selected tab is aria-selected.
Do not put tabs inside tabs
One tablist per region.
Implementation detail
Proposed CSC Standard. Nested tablists make the arrow-key behavior ambiguous.
Use a second pattern, such as an accordion, inside a panel instead of another tablist.
Check: A panel does not contain another tablist.
Let the tablist wrap
Underline, pills, segmented, and boxed lists wrap instead of forcing page scroll.
Implementation detail
Proposed CSC Standard. A nowrap tab strip hides panels at 320px.
Allow wrap. Do not add overflow-x on the page.
Check: At 320px every tab can be reached without scrolling the document sideways.
Restrictions
- TAB-002 Do not put tabs inside tabs. One tablist per region.
Accessibility
- Arrow keys between tabs.
- Selected state is programmatic.
- No nested tablists.
Responsive behavior
- Wrap the tablist.
- Panels use the full column width.
Component states
Selected
aria-selected true and the panel visible.
Unselected
The panel is hidden and not in the tab sequence of the panel contents.
Correct implementation
The selected tab is named and underlined in #2A338F.
Imports: None. Dependencies: None. Rules: TAB-001.
export function RecordTabs() {
return (
<div role="tablist" aria-label="Record">
<button type="button" role="tab" aria-selected="true" style={{ color: '#2A338F', borderBottom: '2px solid #2A338F' }}>Details</button>
<button type="button" role="tab" aria-selected="false">History</button>
</div>
);
}Incorrect implementation
No incorrect example is published for this component.
Common mistakes
- Using tabs as site navigation.
- A second tablist inside a panel.
Testing checklist
Agent prompts for this component are in the AI Development Hub.