--- name: tab-navigation description: Tabs swap views under a shared context. Use when designing tabbed layouts, settings pages, detail views or dashboards with several data views. metadata: priority: 7 pathPatterns: - "components/**" - "src/components/**" - "**/*.tsx" - "**/*.jsx" - "design-system/**" - "ui/**" promptSignals: phrases: - "tab" - "tabs" - "tab panel" - "tabbed" - "tab navigation" - "tab bar" - "tab strip" - "content switcher" - "pivot" retrieval: aliases: - tab navigation - tab panel - tabbed interface - content switcher - tab bar - pivot control intents: - design a tabbed layout - add tabs to a detail view - organise content with tabs - switch between data views - build a settings page with tabs examples: - add tabs to this product detail page - design a settings screen with tab navigation - organise these data views with a tab strip - make it easy to switch between different reports --- # Tab Navigation Tabs organise related content under a shared context. The tab strip communicates the full set of available views; switching tabs swaps the content panel without a page navigation. They work best when all views share a heading, a primary action, or a common subject — tabs that have nothing to do with each other belong in separate pages. --- ## When to Use Tabs — and When Not To | Use tabs when… | Use something else when… | |---|---| | 2–7 views share a common context (same record, same settings section) | There are more than 7–8 tabs — use a sidebar or section nav instead | | Users switch between views frequently during a session | The content is sequential (use a stepper/wizard instead) | | All tabs are equally valid entry points | One view is clearly primary — put the rest in a secondary nav or overflow | | The views share a header or set of page-level actions | Each "tab" requires a different header and layout — use separate pages | --- ## Tab Types Choose the visual style that fits the layout context. ### Underline / Indicator Tabs A horizontal strip with a sliding underline or bottom border on the active tab. The lightest treatment — appropriate for page-level tabs where the tab strip sits inside the content area. ``` Overview | Activity | Settings ────────── ``` ### Contained / Boxed Tabs Each tab is a distinct box; the active tab appears connected to the panel below. Higher visual weight — appropriate for prominent tab groups near the top of a screen or within a card. ### Pill / Button Tabs Rounded capsules that toggle between states. Lower emphasis — appropriate for secondary content switches within a section (not page-level). Often used for view toggles (e.g. "List / Grid / Map"). --- ## Anatomy ``` ┌─────────────────────────────────────────────────┐ │ Tab A │ Tab B │ Tab C │ │ ← Tab strip (role="tablist") ├─────────┴─────────────────────────────────────────┤ │ │ │ Tab panel content │ ← Tab panel (role="tabpanel") │ │ └───────────────────────────────────────────────────┘ ``` - **Tab strip:** Fixed height (typically 40–48px). Does not scroll with the page — consider making it sticky when the page is long. - **Tab panel:** Fills the remaining available height. The panel, not the tab strip, scrolls when content overflows. - **Active indicator:** A 2–3px bottom border in `--color-primary` for underline tabs; filled background for contained/pill tabs. --- ## States | State | Visual treatment | |---|---| | Active | Primary colour indicator; label in `--color-text-primary` or primary | | Inactive | Muted label (`--color-text-secondary`); no indicator | | Hover | Subtle background shift (`--color-grey-50`); label slightly darkens | | Focus | Visible focus ring (`outline: 2px solid --color-primary; outline-offset: 2px`) | | Disabled | Reduced opacity (`0.4`); `cursor: not-allowed`; never the active tab | Never disable the active tab. If content is unavailable, show it inside the panel with an explanation rather than disabling the tab. --- ## Tab Overflow When the tab strip is wider than its container, do not wrap tabs onto multiple lines; it destroys the strip metaphor. Three ways out, in order of preference. ### Select fallback Measure the strip; when its content is wider than its container, render a native `