Skip to content

Tabs

Tabs switch between panes of related content that share one place on the screen, such as the profile, documents and interviews of one candidate.

Line and filled

Filled, on a candidate's record
  • Ana Kovač moved Suman Tamang to Interview2 min ago
  • The work permit for Rajesh Kumar was approved18 min ago
  • Jomar Santos applied for Care assistant, Graz1 h ago
  • Marko Petrović mentioned you on Welders, Split3 h ago
  • Ivana shared the visa folder of Bishnu RaiYesterday
Line, in the notifications tray

WerkOS draws tabs in two ways. On a full screen or in a toolbar, the chosen tab sits in a filled box. Inside a tray or a panel, a blue line under the label marks it, over a thin rule that runs under the row.

When to use it

Use tabs for two to six panes of one thing, such as the profile, documents and interviews of a candidate, or the lists of a notifications tray.

To go to another page, use a link. To show the same candidates as a table or a board, use a segmented control. To act, such as Send offer, use a button.

Anatomy

A row of labels. A line or a filled box marks the chosen one. An icon or a count can join a label.

Label
13 px on 20 px, weight 500
Line tab
34 px high, 8 px at the sides, 44 px on touch
Line
2 px, 4 px in from each edge, on a 1 px rule
--brand-blue
Filled tab
36 px high, 12 px at the sides, 8 px radius, 44 px on touch
--surface-control
Space between tabs
4 px
--space-1
Icon
16 px, 8 px before the label
Count
Counter, 8 px after the label

States

A chosen line tab turns bold inside the width it always keeps, so the row does not shift. A filled tab keeps its weight. No tab is ever disabled: when a pane has nothing to show, the pane says why.

At rest
Muted ink
--text-muted
Hover
Full ink, no fill
--text
Chosen, line
Full ink, bold, the blue line
--brand-blue
Chosen, filled
Full ink on the control fill
--surface-control
Focus
2 px ring around the tab
--focus-ring

Behavior

The line slides to the new tab in 200 ms, or moves at once with reduced motion.

When the next pane shows at once, the arrow keys choose as they move. When a pane has to load, such as a candidate's documents, the arrows only move focus and Enter chooses, so passing over a tab loads nothing.

Panes keep their state while hidden, so a half written note survives a switch. Tabs stay on one line: if they do not fit, shorten the labels. Below 640 px, a select takes the place of the row.

Keyboard and screen readers

The row is a tab list with a name. Each tab points to its pane and each pane back to its tab, so a screen reader says which tab you are on and how many there are.

Tab
Enters the row at the chosen tab, then moves into the pane
Left and Right
Move between tabs
Home and End
Jump to the first or last tab
Enter or Space
Chooses the focused tab when panes load

Permitted and not permitted

Permitted

  • Short nouns in sentence case

    Profile, Documents, Interviews.

  • A count after a label

    Only above zero, such as Unread 4.

  • Icons on every tab or on none

    A lone icon pulls the eye to one tab.

Not permitted

  • Tabs that open other pages

    Tabs promise that you stay on the page. Use links.

  • A disabled tab

    Keep it, and explain the empty pane inside it.

  • More than six tabs

    People stop reading them. Group the panes or use a select.

NextMobile navigation

Tabs

Switch between two to six panes of related content that share one place on the screen.

  • Kind: component
  • Page: https://design.werklist.com/components/tabs
  • Version: 2.1.2

When to use it

  • The parts of one record, such as the profile, documents and interviews of a candidate.
  • Lists inside one surface, such as All and Unread in a notifications tray.

When not to use it

  • Going to another page: use a link or navigation.
  • Showing the same data another way (table, board, chart): use a segmented control.
  • Running a command such as Send offer: use a button.
  • Steps in a fixed order: use a form.
  • More than six panes.

Rules

  • Two to six tabs.
  • Tabs never wrap or scroll sideways. Shorten the labels, and below 640 px replace the row with a select.
  • A pane keeps its state while hidden, so a half written note survives a switch.
  • Icons on every tab or on none.

Anatomy

  • Tab list: a horizontal row with a name, 4 px between tabs (--space-1)
  • Label: 13 px on 20 px, weight 500. A chosen line tab turns bold inside the width it always keeps
  • Line tab: 34 px high, 8 px at each side. On a touch screen at least 44 by 44 px, 16 px at each side (--space-2)
  • Line: 2 px high, brand blue, 4 px in from the edges of the tab, rounded ends, on a 1 px rule under the whole row (--brand-blue, --border-rule, --radius-full)
  • Filled tab: 36 px high, 44 px on a touch screen, 12 px at each side, radius 8 px. The chosen tab sits on the control fill (--surface-control, --radius-lg, --space-3)
  • Icon: 16 px, 8 px before the label, on every tab or on none
  • Count: a Counter 8 px after the label, in tabular digits, shown only above zero
  • Panel: the pane of a tab, reachable with Tab when it holds nothing that takes focus
  • Phone select: below 640 px, for a row that does not fit: 44 px, 16 px chevron, on the field fill of WerkOS. In light a faint ink wash with no edge, in dark a faint fill with a 1 px inset ring (--glass-fill-input, --input-border)

Variants

  • Line: Inside a tray or a raised panel.
  • Filled: On a full screen or in a toolbar.

States

  • Rest: Muted ink (--text-muted)
  • Hover: Full ink, no fill (--text)
  • Chosen, line: Full ink, weight 700, the blue line under it, aria-selected true (--text, --brand-blue)
  • Chosen, filled: Full ink on the control fill, weight kept, aria-selected true (--text, --surface-control)
  • Pressed, filled: Scales to 0.98, or holds still with reduced motion
  • Focus: 2 px ring, 2 px offset (--focus-ring)
  • Line motion: Slides to the new tab in 200 ms, or moves at once with reduced motion (--duration-base, --ease-standard)
  • Forced colors: The line is drawn in the system text color, and a chosen filled tab keeps a 1 px outline

Keyboard

  • Tab: Enters the row at the chosen tab. The next Tab moves into the pane
  • ArrowLeft, ArrowRight: Previous or next tab. Chooses it at once when the pane shows at once
  • Home, End: First or last tab
  • Enter, Space: Chooses the focused tab when a pane has to load

Accessibility

  • The row is a tablist with a name.
  • Each tab: role tab, aria-selected, aria-controls its pane. Only the chosen tab is in the tab order.
  • Each pane: role tabpanel, labelled by its tab.
  • No tab is disabled. An empty pane says why it is empty.
  • Rest ink meets 4.5 to 1 in both themes.
  • A count is read as part of the name of its tab.

Content

  • Nouns or short noun phrases in sentence case, parallel, without end punctuation: Profile, Documents, Interviews.
  • One or two words each. Give a shorter phone label when a row does not fit at 360 px.
  • Counts only above zero.

Tokens

  • --space-1
  • --space-2
  • --space-3
  • --text
  • --text-muted
  • --brand-blue
  • --border-rule
  • --surface-control
  • --radius-lg
  • --radius-full
  • --glass-fill-input
  • --input-border
  • --focus-ring
  • --duration-base
  • --ease-standard

JSON

{
  "title": "Tabs",
  "path": "/components/tabs",
  "url": "https://design.werklist.com/components/tabs",
  "text": "https://design.werklist.com/agent/components/tabs",
  "summary": "Switch between panes of related content in one place on the screen, without leaving the page.",
  "version": "2.1.2",
  "kind": "component",
  "name": "Tabs",
  "purpose": "Switch between two to six panes of related content that share one place on the screen.",
  "use": [
    "The parts of one record, such as the profile, documents and interviews of a candidate.",
    "Lists inside one surface, such as All and Unread in a notifications tray."
  ],
  "avoid": [
    "Going to another page: use a link or navigation.",
    "Showing the same data another way (table, board, chart): use a segmented control.",
    "Running a command such as Send offer: use a button.",
    "Steps in a fixed order: use a form.",
    "More than six panes."
  ],
  "anatomy": [
    {
      "part": "Tab list",
      "measure": "a horizontal row with a name, 4 px between tabs",
      "token": "--space-1"
    },
    {
      "part": "Label",
      "measure": "13 px on 20 px, weight 500. A chosen line tab turns bold inside the width it always keeps"
    },
    {
      "part": "Line tab",
      "measure": "34 px high, 8 px at each side. On a touch screen at least 44 by 44 px, 16 px at each side",
      "token": "--space-2"
    },
    {
      "part": "Line",
      "measure": "2 px high, brand blue, 4 px in from the edges of the tab, rounded ends, on a 1 px rule under the whole row",
      "token": "--brand-blue, --border-rule, --radius-full"
    },
    {
      "part": "Filled tab",
      "measure": "36 px high, 44 px on a touch screen, 12 px at each side, radius 8 px. The chosen tab sits on the control fill",
      "token": "--surface-control, --radius-lg, --space-3"
    },
    {
      "part": "Icon",
      "measure": "16 px, 8 px before the label, on every tab or on none"
    },
    {
      "part": "Count",
      "measure": "a Counter 8 px after the label, in tabular digits, shown only above zero"
    },
    {
      "part": "Panel",
      "measure": "the pane of a tab, reachable with Tab when it holds nothing that takes focus"
    },
    {
      "part": "Phone select",
      "measure": "below 640 px, for a row that does not fit: 44 px, 16 px chevron, on the field fill of WerkOS. In light a faint ink wash with no edge, in dark a faint fill with a 1 px inset ring",
      "token": "--glass-fill-input, --input-border"
    }
  ],
  "variants": [
    {
      "name": "Line",
      "use": "Inside a tray or a raised panel."
    },
    {
      "name": "Filled",
      "use": "On a full screen or in a toolbar."
    }
  ],
  "states": [
    {
      "name": "Rest",
      "change": "Muted ink",
      "tokens": [
        "--text-muted"
      ]
    },
    {
      "name": "Hover",
      "change": "Full ink, no fill",
      "tokens": [
        "--text"
      ]
    },
    {
      "name": "Chosen, line",
      "change": "Full ink, weight 700, the blue line under it, aria-selected true",
      "tokens": [
        "--text",
        "--brand-blue"
      ]
    },
    {
      "name": "Chosen, filled",
      "change": "Full ink on the control fill, weight kept, aria-selected true",
      "tokens": [
        "--text",
        "--surface-control"
      ]
    },
    {
      "name": "Pressed, filled",
      "change": "Scales to 0.98, or holds still with reduced motion"
    },
    {
      "name": "Focus",
      "change": "2 px ring, 2 px offset",
      "tokens": [
        "--focus-ring"
      ]
    },
    {
      "name": "Line motion",
      "change": "Slides to the new tab in 200 ms, or moves at once with reduced motion",
      "tokens": [
        "--duration-base",
        "--ease-standard"
      ]
    },
    {
      "name": "Forced colors",
      "change": "The line is drawn in the system text color, and a chosen filled tab keeps a 1 px outline"
    }
  ],
  "keys": [
    {
      "key": "Tab",
      "action": "Enters the row at the chosen tab. The next Tab moves into the pane"
    },
    {
      "key": "ArrowLeft, ArrowRight",
      "action": "Previous or next tab. Chooses it at once when the pane shows at once"
    },
    {
      "key": "Home, End",
      "action": "First or last tab"
    },
    {
      "key": "Enter, Space",
      "action": "Chooses the focused tab when a pane has to load"
    }
  ],
  "accessibility": [
    "The row is a tablist with a name.",
    "Each tab: role tab, aria-selected, aria-controls its pane. Only the chosen tab is in the tab order.",
    "Each pane: role tabpanel, labelled by its tab.",
    "No tab is disabled. An empty pane says why it is empty.",
    "Rest ink meets 4.5 to 1 in both themes.",
    "A count is read as part of the name of its tab."
  ],
  "content": [
    "Nouns or short noun phrases in sentence case, parallel, without end punctuation: Profile, Documents, Interviews.",
    "One or two words each. Give a shorter phone label when a row does not fit at 360 px.",
    "Counts only above zero."
  ],
  "rules": [
    "Two to six tabs.",
    "Tabs never wrap or scroll sideways. Shorten the labels, and below 640 px replace the row with a select.",
    "A pane keeps its state while hidden, so a half written note survives a switch.",
    "Icons on every tab or on none."
  ],
  "tokens": [
    "--space-1",
    "--space-2",
    "--space-3",
    "--text",
    "--text-muted",
    "--brand-blue",
    "--border-rule",
    "--surface-control",
    "--radius-lg",
    "--radius-full",
    "--glass-fill-input",
    "--input-border",
    "--focus-ring",
    "--duration-base",
    "--ease-standard"
  ]
}

Raw file: https://design.werklist.com/agent/components/tabs