$npx -y skills add dembrandt/dembrandt-skills --skill tab-navigationTabs organise related content under a shared context — switching tabs swaps the view without leaving the page. Use when a screen has multiple distinct content areas that share a common header or action set, and when the user needs to switch between them frequently. Use when desig
| 1 | # Tab Navigation |
| 2 | |
| 3 | 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. |
| 4 | |
| 5 | --- |
| 6 | |
| 7 | ## When to Use Tabs — and When Not To |
| 8 | |
| 9 | | Use tabs when… | Use something else when… | |
| 10 | |---|---| |
| 11 | | 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 | |
| 12 | | Users switch between views frequently during a session | The content is sequential (use a stepper/wizard instead) | |
| 13 | | All tabs are equally valid entry points | One view is clearly primary — put the rest in a secondary nav or overflow | |
| 14 | | The views share a header or set of page-level actions | Each "tab" requires a different header and layout — use separate pages | |
| 15 | |
| 16 | --- |
| 17 | |
| 18 | ## Tab Types |
| 19 | |
| 20 | Choose the visual style that fits the layout context. |
| 21 | |
| 22 | ### Underline / Indicator Tabs |
| 23 | 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. |
| 24 | |
| 25 | ``` |
| 26 | Overview | Activity | Settings |
| 27 | ────────── |
| 28 | ``` |
| 29 | |
| 30 | ### Contained / Boxed Tabs |
| 31 | 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. |
| 32 | |
| 33 | ### Pill / Button Tabs |
| 34 | 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"). |
| 35 | |
| 36 | --- |
| 37 | |
| 38 | ## Anatomy |
| 39 | |
| 40 | ``` |
| 41 | ┌─────────────────────────────────────────────────┐ |
| 42 | │ Tab A │ Tab B │ Tab C │ │ ← Tab strip (role="tablist") |
| 43 | ├─────────┴─────────────────────────────────────────┤ |
| 44 | │ │ |
| 45 | │ Tab panel content │ ← Tab panel (role="tabpanel") |
| 46 | │ │ |
| 47 | └───────────────────────────────────────────────────┘ |
| 48 | ``` |
| 49 | |
| 50 | - **Tab strip:** Fixed height (typically 40–48px). Does not scroll with the page — consider making it sticky when the page is long. |
| 51 | - **Tab panel:** Fills the remaining available height. The panel, not the tab strip, scrolls when content overflows. |
| 52 | - **Active indicator:** A 2–3px bottom border in `--color-primary` for underline tabs; filled background for contained/pill tabs. |
| 53 | |
| 54 | --- |
| 55 | |
| 56 | ## States |
| 57 | |
| 58 | | State | Visual treatment | |
| 59 | |---|---| |
| 60 | | Active | Primary colour indicator; label in `--color-text-primary` or primary | |
| 61 | | Inactive | Muted label (`--color-text-secondary`); no indicator | |
| 62 | | Hover | Subtle background shift (`--color-grey-50`); label slightly darkens | |
| 63 | | Focus | Visible focus ring (`outline: 2px solid --color-primary; outline-offset: 2px`) | |
| 64 | | Disabled | Reduced opacity (`0.4`); `cursor: not-allowed`; never the active tab | |
| 65 | |
| 66 | Never disable the active tab. If content is unavailable, show it inside the panel with an explanation rather than disabling the tab. |
| 67 | |
| 68 | --- |
| 69 | |
| 70 | ## Tab Overflow |
| 71 | |
| 72 | When the tab strip is wider than the viewport or container, do not wrap tabs onto multiple lines — it destroys the strip metaphor. |
| 73 | |
| 74 | ### Scrollable strip |
| 75 | The strip scrolls horizontally. Show a fade/gradient at the right edge to signal overflow. On touch devices this is the preferred solution. |
| 76 | |
| 77 | ```css |
| 78 | .tab-strip { |
| 79 | display: flex; |
| 80 | overflow-x: auto; |
| 81 | scrollbar-width: none; /* hide scrollbar visually on desktop */ |
| 82 | } |
| 83 | .tab-strip::after { |
| 84 | content: ''; |
| 85 | position: absolute |