Skip to main content

Sidebar

The side navigation of an app, open while people work.

Left out of Content first Sidebar is app navigation, not a website's main navigation. Content first is a public site; navigation menu carries the site sections and sheet the phone menu. Use instead: Navigation menu, Sheet

See it live​

Start Storybook to see it live: npm run storybook

When to use it​

  • Use it when: Apps with several sections people move between all session.
  • Not when: A website's main navigation (navigation menu), or a few sections that fit in tabs.

Instead:

Variants​

What each variant is for in any design system, then what Content first decided and why. Each sample is the live story with that variant set.

defaultvariantNot decided yet
Start Storybook to see it live

What it is for

Menu items with no border; hover shows the item.

✓Most apps: quiet next to the content.
✕Items that need extra separation.

In Content first

Not decided yet.

outlinevariantNot decided yet
Start Storybook to see it live

What it is for

Menu items with a border.

✓Items that need extra separation from a busy background.
✕A quiet sidebar next to dense content.

In Content first

Not decided yet.

defaultsizeNot decided yet
Start Storybook to see it live

What it is for

The normal row height.

✓Most menu items.
✕Very long lists.

In Content first

Not decided yet.

smsizeNot decided yet
Start Storybook to see it live

What it is for

A smaller row.

✓Long or secondary lists.
✕Touch screens.

In Content first

Not decided yet.

lgsizeNot decided yet
Start Storybook to see it live

What it is for

A taller row with room for an icon and two lines.

✓A workspace or account switcher at the top.
✕Ordinary menu items.

In Content first

Not decided yet.

Words​

  • Write to one person: "you", not "users".
  • Short sentences with room to breathe.
  • Explain why before asking for anything.
  • Use: Read, Save for later, You, Next issue. Avoid: Click here, Submit, Users, Content.

The labels components use, from the voice tokens:

  • content.action.commit: Save
  • content.action.cancel: Not now
  • content.action.destroy: Remove
  • content.action.retry: Try again
  • content.action.empty-action: Browse guides

See Voice and tone for the whole voice.

Accessibility and keyboard​

Test before you ship:

  • It is a navigation landmark; the current section is marked; collapsing keeps names for icons. undefined

Use it in code​

npx open-ds add sidebar

The component reads only component keys and semantic tokens, so it follows the brand and mode on <html>.

Tokens it reads​

Sidebar reads 113 tokens of its own, each an alias of a semantic token. Each row is one part: its own token, the semantic it aliases, and the value it ends at. Change a semantic and every component that reads it follows; override one of Sidebar's tokens to change Sidebar alone.

Changes with theme

Content first decides what changes when you switch theme. Here a switch changes colors only, so the marked rows differ between light and dark; everything else holds steady.

PartIts token and the semantic it aliasesValue
Wrapper
Fill
Changes with theme
component.sidebar.wrapper.backgroundcolor.surface.defaultvar(--sidebar-wrapper-background)Lightstone.light.0:#FFFFFFDarkstone.dark.50:#1F1B16
Sidebar
Fill
Changes with theme
component.sidebar.backgroundcolor.surface.defaultvar(--sidebar-background)Lightstone.light.0:#FFFFFFDarkstone.dark.50:#1F1B16
Text
Changes with theme
component.sidebar.labelcolor.text.primaryvar(--sidebar-label)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Paddingcomponent.sidebar.paddingcomponent-spacing-map.x2var(--sidebar-padding)space.8:0.5rem
Background hover
Changes with theme
on hover
component.sidebar.background-hovercolor.surface.defaultvar(--sidebar-background-hover)Lightstone.light.0:#FFFFFFDarkstone.dark.50:#1F1B16
Cornercomponent.sidebar.radiusradius.controlvar(--sidebar-radius)radius.8:0.5rem
Text sizecomponent.sidebar.font-sizetype.body.font-sizevar(--sidebar-font-size)font.size.18:1.125rem
Focus ring
Changes with theme
component.sidebar.focus-ringcolor.border.focusvar(--sidebar-focus-ring)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Padding rightcomponent.sidebar.padding-rightcomponent-spacing-map.x8var(--sidebar-padding-right)space.48:3rem
Sizecomponent.sidebar.sizesize.control.defaultvar(--sidebar-size)size.48:3rem
Background hover 2
Changes with theme
on hover
component.sidebar.background-hover-2color.surface.sunkenvar(--sidebar-background-hover-2)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Label hover
Changes with theme
on hover
component.sidebar.label-hovercolor.text.primaryvar(--sidebar-label-hover)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Background active
Changes with theme
component.sidebar.background-activecolor.surface.sunkenvar(--sidebar-background-active)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Label active
Changes with theme
component.sidebar.label-activecolor.text.primaryvar(--sidebar-label-active)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Disabled opacity disabled
when disabled
component.sidebar.disabled-opacity-disabledopacity.disabledvar(--sidebar-disabled-opacity-disabled)opacity.40:0.4
Background 2
Changes with theme
component.sidebar.background-2color.surface.sunkenvar(--sidebar-background-2)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Weightcomponent.sidebar.font-weighttype.label.font-weightvar(--sidebar-font-weight)font.weight.600:600
Focuscomponent.sidebar.focusborder-width.focusvar(--sidebar-focus)border-width.2:2px
Background open hover
Changes with theme
when open, on hover
component.sidebar.background-open-hovercolor.surface.sunkenvar(--sidebar-background-open-hover)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Label open hover
Changes with theme
when open, on hover
component.sidebar.label-open-hovercolor.text.primaryvar(--sidebar-label-open-hover)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Icon sizecomponent.sidebar.icon-sizesize.iconvar(--sidebar-icon-size)size.16:1rem
Focus ring focus
Changes with theme
on focus
component.sidebar.focus-ring-focuscolor.border.focusvar(--sidebar-focus-ring-focus)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Focus ring offset focus
Changes with theme
on focus
component.sidebar.focus-ring-offset-focuscolor.surface.canvasvar(--sidebar-focus-ring-offset-focus)Lightstone.light.50:#FFFDF8Darkstone.dark.0:#14110D
Heightcomponent.sidebar.heightsize.iconvar(--sidebar-height)size.16:1rem
Font size 2component.sidebar.font-size-2type.caption.font-sizevar(--sidebar-font-size-2)font.size.14:0.875rem
Gap
Speedcomponent.sidebar.gap.durationmotion.duration.feedbackvar(--sidebar-gap-duration)duration.moderate:200ms
Valuecomponent.sidebar.gapspace.gap.defaultvar(--sidebar-gap)space.16:1rem
Container
Speedcomponent.sidebar.container.durationmotion.duration.feedbackvar(--sidebar-container-duration)duration.moderate:200ms
Inner
Fill
Changes with theme
component.sidebar.inner.backgroundcolor.surface.defaultvar(--sidebar-inner-background)Lightstone.light.0:#FFFFFFDarkstone.dark.50:#1F1B16
Cornercomponent.sidebar.inner.radiusradius.containervar(--sidebar-inner-radius)radius.12:0.75rem
Border
Changes with theme
component.sidebar.inner.bordercolor.border.defaultvar(--sidebar-inner-border)Lightstone.light.200:#E4DDD0Darkstone.dark.100:#2E2A24
Shadowcomponent.sidebar.inner.shadowelevation.cardvar(--sidebar-inner-shadow)shadow.none
Rail
Background hover
Changes with theme
on hover
component.sidebar.rail.background-hovercolor.border.defaultvar(--sidebar-rail-background-hover)Lightstone.light.200:#E4DDD0Darkstone.dark.100:#2E2A24
Inset
Fill
Changes with theme
component.sidebar.inset.backgroundcolor.surface.canvasvar(--sidebar-inset-background)Lightstone.light.50:#FFFDF8Darkstone.dark.0:#14110D
Cornercomponent.sidebar.inset.radiusradius.containervar(--sidebar-inset-radius)radius.12:0.75rem
Shadowcomponent.sidebar.inset.shadowelevation.cardvar(--sidebar-inset-shadow)shadow.none
Input
Heightcomponent.sidebar.input.heightsize.control.defaultvar(--sidebar-input-height)size.48:3rem
Fill
Changes with theme
component.sidebar.input.backgroundcolor.surface.canvasvar(--sidebar-input-background)Lightstone.light.50:#FFFDF8Darkstone.dark.0:#14110D
Header
Gapcomponent.sidebar.header.gapspace.gap.defaultvar(--sidebar-header-gap)space.16:1rem
Paddingcomponent.sidebar.header.paddingcomponent-spacing-map.x2var(--sidebar-header-padding)space.8:0.5rem
Footer
Gapcomponent.sidebar.footer.gapspace.gap.defaultvar(--sidebar-footer-gap)space.16:1rem
Paddingcomponent.sidebar.footer.paddingcomponent-spacing-map.x2var(--sidebar-footer-padding)space.8:0.5rem
Separator
Fill
Changes with theme
component.sidebar.separator.backgroundcolor.border.defaultvar(--sidebar-separator-background)Lightstone.light.200:#E4DDD0Darkstone.dark.100:#2E2A24
Content
Gapcomponent.sidebar.content.gapspace.gap.defaultvar(--sidebar-content-gap)space.16:1rem
Group
Paddingcomponent.sidebar.group.paddingcomponent-spacing-map.x2var(--sidebar-group-padding)space.8:0.5rem
Label heightcomponent.sidebar.group.label.heightsize.control.defaultvar(--sidebar-group-label-height)size.48:3rem
Label radiuscomponent.sidebar.group.label.radiusradius.controlvar(--sidebar-group-label-radius)radius.8:0.5rem
Label padding xcomponent.sidebar.group.label.padding-xcomponent-spacing-map.x2var(--sidebar-group-label-padding-x)space.8:0.5rem
Label font sizecomponent.sidebar.group.label.font-sizetype.caption.font-sizevar(--sidebar-group-label-font-size)font.size.14:0.875rem
Label font weightcomponent.sidebar.group.label.font-weighttype.label.font-weightvar(--sidebar-group-label-font-weight)font.weight.600:600
Label label
Changes with theme
component.sidebar.group.label.labelcolor.text.primaryvar(--sidebar-group-label-label)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Label focus ring
Changes with theme
component.sidebar.group.label.focus-ringcolor.border.focusvar(--sidebar-group-label-focus-ring)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Label durationcomponent.sidebar.group.label.durationmotion.duration.feedbackvar(--sidebar-group-label-duration)duration.moderate:200ms
Label icon sizecomponent.sidebar.group.label.icon-sizesize.iconvar(--sidebar-group-label-icon-size)size.16:1rem
Label focus
on focus
component.sidebar.group.label.focusborder-width.focusvar(--sidebar-group-label-focus)border-width.2:2px
Label focus ring focus
Changes with theme
on focus
component.sidebar.group.label.focus-ring-focuscolor.border.focusvar(--sidebar-group-label-focus-ring-focus)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Label focus ring offset focus
Changes with theme
on focus
component.sidebar.group.label.focus-ring-offset-focuscolor.surface.canvasvar(--sidebar-group-label-focus-ring-offset-focus)Lightstone.light.50:#FFFDF8Darkstone.dark.0:#14110D
Action radiuscomponent.sidebar.group.action.radiusradius.controlvar(--sidebar-group-action-radius)radius.8:0.5rem
Action label
Changes with theme
component.sidebar.group.action.labelcolor.text.primaryvar(--sidebar-group-action-label)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Action focus ring
Changes with theme
component.sidebar.group.action.focus-ringcolor.border.focusvar(--sidebar-group-action-focus-ring)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Action background hover
Changes with theme
on hover
component.sidebar.group.action.background-hovercolor.surface.sunkenvar(--sidebar-group-action-background-hover)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Action label hover
Changes with theme
on hover
component.sidebar.group.action.label-hovercolor.text.primaryvar(--sidebar-group-action-label-hover)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Action icon sizecomponent.sidebar.group.action.icon-sizesize.iconvar(--sidebar-group-action-icon-size)size.16:1rem
Action focus
on focus
component.sidebar.group.action.focusborder-width.focusvar(--sidebar-group-action-focus)border-width.2:2px
Action focus ring focus
Changes with theme
on focus
component.sidebar.group.action.focus-ring-focuscolor.border.focusvar(--sidebar-group-action-focus-ring-focus)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Action focus ring offset focus
Changes with theme
on focus
component.sidebar.group.action.focus-ring-offset-focuscolor.surface.canvasvar(--sidebar-group-action-focus-ring-offset-focus)Lightstone.light.50:#FFFDF8Darkstone.dark.0:#14110D
Content font sizecomponent.sidebar.group.content.font-sizetype.body.font-sizevar(--sidebar-group-content-font-size)font.size.18:1.125rem
Menu
Gapcomponent.sidebar.menu.gapspace.gap.tightvar(--sidebar-menu-gap)space.8:0.5rem
Action radiuscomponent.sidebar.menu.action.radiusradius.controlvar(--sidebar-menu-action-radius)radius.8:0.5rem
Action label
Changes with theme
component.sidebar.menu.action.labelcolor.text.primaryvar(--sidebar-menu-action-label)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Action focus ring
Changes with theme
component.sidebar.menu.action.focus-ringcolor.border.focusvar(--sidebar-menu-action-focus-ring)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Action background hover
Changes with theme
on hover
component.sidebar.menu.action.background-hovercolor.surface.sunkenvar(--sidebar-menu-action-background-hover)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Action label hover
Changes with theme
on hover
component.sidebar.menu.action.label-hovercolor.text.primaryvar(--sidebar-menu-action-label-hover)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Action icon sizecomponent.sidebar.menu.action.icon-sizesize.iconvar(--sidebar-menu-action-icon-size)size.16:1rem
Action focus
on focus
component.sidebar.menu.action.focusborder-width.focusvar(--sidebar-menu-action-focus)border-width.2:2px
Action focus ring focus
Changes with theme
on focus
component.sidebar.menu.action.focus-ring-focuscolor.border.focusvar(--sidebar-menu-action-focus-ring-focus)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Action focus ring offset focus
Changes with theme
on focus
component.sidebar.menu.action.focus-ring-offset-focuscolor.surface.canvasvar(--sidebar-menu-action-focus-ring-offset-focus)Lightstone.light.50:#FFFDF8Darkstone.dark.0:#14110D
Badge radiuscomponent.sidebar.menu.badge.radiusradius.controlvar(--sidebar-menu-badge-radius)radius.8:0.5rem
Badge padding xcomponent.sidebar.menu.badge.padding-xcomponent-spacing-map.x1var(--sidebar-menu-badge-padding-x)space.4:0.25rem
Badge font sizecomponent.sidebar.menu.badge.font-sizetype.caption.font-sizevar(--sidebar-menu-badge-font-size)font.size.14:0.875rem
Badge font weightcomponent.sidebar.menu.badge.font-weighttype.label.font-weightvar(--sidebar-menu-badge-font-weight)font.weight.600:600
Badge label
Changes with theme
component.sidebar.menu.badge.labelcolor.text.primaryvar(--sidebar-menu-badge-label)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Skeleton heightcomponent.sidebar.menu.skeleton.heightsize.control.defaultvar(--sidebar-menu-skeleton-height)size.48:3rem
Skeleton gapcomponent.sidebar.menu.skeleton.gapspace.gap.defaultvar(--sidebar-menu-skeleton-gap)space.16:1rem
Skeleton radiuscomponent.sidebar.menu.skeleton.radiusradius.controlvar(--sidebar-menu-skeleton-radius)radius.8:0.5rem
Skeleton padding xcomponent.sidebar.menu.skeleton.padding-xcomponent-spacing-map.x2var(--sidebar-menu-skeleton-padding-x)space.8:0.5rem
Sub gapcomponent.sidebar.menu.sub.gapspace.gap.tightvar(--sidebar-menu-sub-gap)space.8:0.5rem
Sub border
Changes with theme
component.sidebar.menu.sub.bordercolor.border.defaultvar(--sidebar-menu-sub-border)Lightstone.light.200:#E4DDD0Darkstone.dark.100:#2E2A24
Sub padding xcomponent.sidebar.menu.sub.padding-xcomponent-spacing-map.x3var(--sidebar-menu-sub-padding-x)space.20:1.25rem
Sub padding ycomponent.sidebar.menu.sub.padding-ycomponent-spacing-map.hairlinevar(--sidebar-menu-sub-padding-y)space.2:0.125rem
Sub button gapcomponent.sidebar.menu.sub.button.gapspace.gap.defaultvar(--sidebar-menu-sub-button-gap)space.16:1rem
Sub button radiuscomponent.sidebar.menu.sub.button.radiusradius.controlvar(--sidebar-menu-sub-button-radius)radius.8:0.5rem
Sub button padding xcomponent.sidebar.menu.sub.button.padding-xcomponent-spacing-map.x2var(--sidebar-menu-sub-button-padding-x)space.8:0.5rem
Sub button label
Changes with theme
component.sidebar.menu.sub.button.labelcolor.text.primaryvar(--sidebar-menu-sub-button-label)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Sub button focus ring
Changes with theme
component.sidebar.menu.sub.button.focus-ringcolor.border.focusvar(--sidebar-menu-sub-button-focus-ring)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Sub button background hover
Changes with theme
on hover
component.sidebar.menu.sub.button.background-hovercolor.surface.sunkenvar(--sidebar-menu-sub-button-background-hover)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Sub button label hover
Changes with theme
on hover
component.sidebar.menu.sub.button.label-hovercolor.text.primaryvar(--sidebar-menu-sub-button-label-hover)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Sub button background active
Changes with theme
component.sidebar.menu.sub.button.background-activecolor.surface.sunkenvar(--sidebar-menu-sub-button-background-active)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Sub button label active
Changes with theme
component.sidebar.menu.sub.button.label-activecolor.text.primaryvar(--sidebar-menu-sub-button-label-active)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Sub button disabled opacity disabled
when disabled
component.sidebar.menu.sub.button.disabled-opacity-disabledopacity.disabledvar(--sidebar-menu-sub-button-disabled-opacity-disabled)opacity.40:0.4
Sub button icon sizecomponent.sidebar.menu.sub.button.icon-sizesize.iconvar(--sidebar-menu-sub-button-icon-size)size.16:1rem
Sub button focus
on focus
component.sidebar.menu.sub.button.focusborder-width.focusvar(--sidebar-menu-sub-button-focus)border-width.2:2px
Sub button focus ring focus
Changes with theme
on focus
component.sidebar.menu.sub.button.focus-ring-focuscolor.border.focusvar(--sidebar-menu-sub-button-focus-ring-focus)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Sub button focus ring offset focus
Changes with theme
on focus
component.sidebar.menu.sub.button.focus-ring-offset-focuscolor.surface.canvasvar(--sidebar-menu-sub-button-focus-ring-offset-focus)Lightstone.light.50:#FFFDF8Darkstone.dark.0:#14110D
Default
Background hover
Changes with theme
component.sidebar.default.background-hovercolor.surface.sunkenvar(--sidebar-default-background-hover)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Label hover
Changes with theme
on hover
component.sidebar.default.label-hovercolor.text.primaryvar(--sidebar-default-label-hover)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Heightcomponent.sidebar.default.heightsize.control.defaultvar(--sidebar-default-height)size.48:3rem
Text sizecomponent.sidebar.default.font-sizetype.body.font-sizevar(--sidebar-default-font-size)font.size.18:1.125rem
Outline
Fill
Changes with theme
component.sidebar.outline.backgroundcolor.surface.canvasvar(--sidebar-outline-background)Lightstone.light.50:#FFFDF8Darkstone.dark.0:#14110D
Background hover
Changes with theme
on hover
component.sidebar.outline.background-hovercolor.surface.sunkenvar(--sidebar-outline-background-hover)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Label hover
Changes with theme
on hover
component.sidebar.outline.label-hovercolor.text.primaryvar(--sidebar-outline-label-hover)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Sm
Text sizecomponent.sidebar.sm.font-sizetype.caption.font-sizevar(--sidebar-sm-font-size)font.size.14:0.875rem
Lg
Text sizecomponent.sidebar.lg.font-sizetype.body.font-sizevar(--sidebar-lg-font-size)font.size.18:1.125rem
From the system
Edge
Changes with theme
color.border.default
straight from the system, through --border
Lightstone.light.200 · #E4DDD0Darkstone.dark.100 · #2E2A24