StartFoundationsComponentsContent

Sidebar

A sidebar is a column of navigation links at the side of an app or docs site. It can collapse out of view or down to a rail of icons.

Stable Figma
OverviewUsageAPIAccessibility
Overview Installation Foundations Color Typography
<tk-sidebar label="Documentation">
  <tk-sidebar-nav-item href="/overview" current>Overview</tk-sidebar-nav-item>
  <tk-sidebar-nav-item href="/install">Installation</tk-sidebar-nav-item>
  <tk-collapsible open>
    <span slot="trigger">Foundations</span>
    <tk-sidebar-nav-item href="/color">Color</tk-sidebar-nav-item>
    <tk-sidebar-nav-item href="/type">Typography</tk-sidebar-nav-item>
  </tk-collapsible>
</tk-sidebar>

Anatomy

Part What it is
tk-sidebar the panel, with three regions: header, content, footer
header slot app chrome above the links, such as a logo or search
content the links; a <nav> landmark that scrolls on its own
footer slot app chrome below the links, such as the account menu
tk-sidebar-nav-item one row: a link, or a row that opens nested rows

Build the rest from other components: a group is a Collapsible, the toggle is your own Icon button, and a row's "more" button is a Menu. While the links scroll, they fade out at the edge; there are no divider lines.

Rows

Inbox Starred Projects Apollo Borealis Archive
<tk-sidebar label="Workspace">
  <tk-sidebar-nav-item href="/inbox"><tk-icon slot="icon" name="mail"></tk-icon>Inbox</tk-sidebar-nav-item>
  <tk-sidebar-nav-item href="/starred" current><tk-icon slot="icon" name="star"></tk-icon>Starred</tk-sidebar-nav-item>
  <tk-sidebar-nav-item open>
    <tk-icon slot="icon" name="bookmark"></tk-icon>Projects
    <tk-sidebar-nav-item slot="sub" href="/apollo">Apollo</tk-sidebar-nav-item>
    <tk-sidebar-nav-item slot="sub" href="/borealis">Borealis</tk-sidebar-nav-item>
  </tk-sidebar-nav-item>
  <tk-sidebar-nav-item href="/archive" disabled>Archive</tk-sidebar-nav-item>
</tk-sidebar>
  • current: marks the page people are on.
  • icon slot: a tk-icon before the label. The rail shows only this.
  • trailing slot: a count Badge or a "more" button after the label.
  • sub slot: nested rows. The row becomes a button that opens them in place, pushing the rows below down. A row with nested rows isn't a link, so leave out href.
  • disabled: dimmed and out of the Tab order.

Collapsing

collapsible When collapsed
offcanvas (default) the panel slides away
icon the panel narrows to a rail of icons, 56px wide
none never collapses

Collapsed rows leave the Tab order and the accessibility tree, so no one can tab into a hidden panel.

The icon rail

The rail shows top-level rows as their icons. Each row keeps its name for screen readers. Anything in the content that isn't a row is hidden, including group captions, search fields, and wrappers around rows, so a sidebar with groups should collapse offcanvas instead. Pick icons that are clear without their labels.

<tk-sidebar id="rail" label="Main" collapsible="icon">
  <tk-sidebar-nav-item href="/inbox"><tk-icon slot="icon" name="mail"></tk-icon>Inbox</tk-sidebar-nav-item>
  <tk-sidebar-nav-item href="/starred"><tk-icon slot="icon" name="star"></tk-icon>Starred</tk-sidebar-nav-item>
</tk-sidebar>
<script>
  document.getElementById('rail').open = false;
</script>

open is on by default; to start collapsed, set the property from script, as above.

The toggle

There is no built-in toggle button. Call toggle() from your own Icon button, named for the action:

<tk-icon-button label="Toggle sidebar" onclick="document.getElementById('nav').toggle()">
  <tk-icon name="menu"></tk-icon>
</tk-icon-button>

Cmd + B on Apple platforms and Ctrl + B elsewhere toggle the sidebar from anywhere on the page, except while typing in a field. Change the shortcut with hotkey, or turn it off with hotkey="". persist remembers whether the sidebar was open, in localStorage under tk-sidebar:open.

Variants

Profile Billing
<tk-sidebar label="Settings" variant="floating">
  <tk-sidebar-nav-item href="/profile" current>Profile</tk-sidebar-nav-item>
  <tk-sidebar-nav-item href="/billing">Billing</tk-sidebar-nav-item>
</tk-sidebar>
  • sidebar (default): flush to the edge of the window, with a hairline on its inner side.
  • floating: an inset card with rounded corners and a shadow.

side="right" pins it to the right edge.

Page layout

The sidebar doesn't move your page content. In a flex row beside your content, it needs nothing: the page reflows as the sidebar narrows. If you position it yourself, offset your content with the same custom properties the sidebar reads:

.app { --tk-sidebar-width: 260px; --tk-sidebar-rail-width: 56px; }
.app main { margin-inline-start: var(--tk-sidebar-width); }
.app tk-sidebar:not([open]) ~ main { margin-inline-start: 0; }
.app tk-sidebar[collapsible='icon']:not([open]) ~ main { margin-inline-start: var(--tk-sidebar-rail-width); }

Mobile

A navigation drawer on a narrow screen is modal, so use a Sheet with the same rows, and hide the sidebar at that width. The sidebar has no breakpoint of its own.

<tk-icon-button label="Open navigation" onclick="document.getElementById('drawer').show()">
  <tk-icon name="menu"></tk-icon>
</tk-icon-button>
<tk-sheet id="drawer" heading="Menu" side="left">
  <tk-sidebar label="Main" collapsible="none">
    <tk-sidebar-nav-item href="/home" current>Home</tk-sidebar-nav-item>
  </tk-sidebar>
</tk-sheet>