Skip to content

Sidebar

CSS

A sidebar is a drawer for navigation or filters. The open state is a checkbox, so there’s no kit JavaScript. Use it when the panel should overlay the main column instead of sitting in the document flow.

The wrapper is .k-sidebar. Order matters: hidden checkbox, then the dimmed-page label (the scrim), then the panel, then main. Labels with for matching the checkbox id toggle it. One in main opens the drawer. One in the panel closes it. Clicking the dimmed page closes it too.

Inside the panel, use the nav parts for a real menu: list, group headings, and links. Mark the active page with aria-current="page". --docked keeps the panel in the document flow from 50em up. --end docks the panel on the inline end. Reduced motion drops the slide.

ClassTypeDescription
k-sidebarcomponentThe wrapper. Child order matters.
k-sidebar__togglepartHidden checkbox holding the open state. Comes first.
k-sidebar__scrimpartLabel over the dimmed page. Clicking it closes the drawer.
k-sidebar__panelpartThe drawer that slides over the main column.
k-sidebar__triggerpartLabel that toggles the checkbox. One to open, one to close.
k-sidebar__trigger--openmodifierOpen control. Hidden when --docked is in the wide layout.
k-sidebar__trigger--closemodifierClose control in the panel. Hidden when --docked is in the wide layout.
k-sidebar__brandpartTop row for a mark and the close trigger.
k-sidebar__brand-markpartTitle or logo in the brand row.
k-sidebar__eyebrowpartSmall uppercase label above the nav.
k-sidebar__navpartWraps the link list.
k-sidebar__listpartUnordered list of links or groups.
k-sidebar__list--nestedmodifierIndented list under a group.
k-sidebar__grouppartdetails wrapping a nested list.
k-sidebar__headingpartsummary for a collapsible group.
k-sidebar__linkpartNav link. Use aria-current="page" for the active item.
k-sidebar__footerpartOptional strip under the nav.
k-sidebar__mainpartThe page content the drawer covers.
k-sidebar--endmodifierDocks the panel on the inline end.
k-sidebar--dockedmodifierKeeps the panel in flow from 50em up. Drawer below that.

Default dock. Open Menu, then Close or the scrim.

<div class="k-sidebar">
<input id="nav" type="checkbox" class="k-sidebar__toggle" />
<label for="nav" class="k-sidebar__scrim"></label>
<aside class="k-sidebar__panel">
<label for="nav" class="k-sidebar__trigger k-sidebar__trigger--close">Close</label>
<nav class="k-sidebar__nav" aria-label="Sidebar">
<ul class="k-sidebar__list">
<li><a class="k-sidebar__link" href="#overview" aria-current="page">Overview</a></li>
<li>
<details class="k-sidebar__group" open>
<summary class="k-sidebar__heading">
<span>Library</span>
<span class="k-icon k-icon--chevron-down k-icon--xs" aria-hidden="true"></span>
</summary>
<ul class="k-sidebar__list k-sidebar__list--nested">
<li><a class="k-sidebar__link" href="#projects">Projects</a></li>
<li><a class="k-sidebar__link" href="#settings">Settings</a></li>
</ul>
</details>
</li>
</ul>
</nav>
</aside>
<div class="k-sidebar__main">
<label for="nav" class="k-sidebar__trigger k-sidebar__trigger--open">Menu</label>
</div>
</div>

The checkbox is the state. Hide it with .k-sidebar__toggle. Don’t display: none it or the labels stop working. Triggers are <label for="…"> so a click or the associated input both work. Put a visible Close in the panel. The scrim is the same toggle. Give the panel a heading or labelled links so the drawer has a name. Mark the current page with aria-current="page".

Do

  • Keep the order: checkbox, scrim, panel, main.
  • Match every for to the checkbox id.
  • Put a visible Close in the panel.
  • Use .k-sidebar__link and groups for navigation chrome.

Don’t

  • Hide the checkbox with display: none. The labels stop working.
  • Use a plain drawer for content that should stay in the document flow — use --docked when the rail should stay open on large screens.