Sidebar
A fixed-width side panel that can be used to display navigation, content, or other information in sidebar layouts.
Examples
Basic usage
<aside class="sidebar">
<nav class="sidebar-nav" aria-label="Primary">
<a href="#" class="sidebar-link" aria-current="page">
<svg
class="sidebar-link-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<rect x="3" y="3" width="7" height="7" />
<rect x="14" y="3" width="7" height="7" />
<rect x="3" y="14" width="7" height="7" />
<rect x="14" y="14" width="7" height="7" />
</svg>
<span class="sidebar-link-text">Dashboard</span>
</a>
<a href="#" class="sidebar-link">
<svg
class="sidebar-link-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path
d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"
/>
</svg>
<span class="sidebar-link-text">Projects</span>
</a>
<a href="#" class="sidebar-link">
<svg
class="sidebar-link-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<circle cx="12" cy="12" r="3" />
<path
d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"
/>
</svg>
<span class="sidebar-link-text">Settings</span>
</a>
</nav>
</aside>
Header and footer
<aside class="sidebar">
<header>
<strong>Acme</strong>
</header>
<nav class="sidebar-nav" aria-label="Primary">
<a href="#" class="sidebar-link" aria-current="page">
<svg
class="sidebar-link-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<rect x="3" y="3" width="7" height="7" />
<rect x="14" y="3" width="7" height="7" />
<rect x="3" y="14" width="7" height="7" />
<rect x="14" y="14" width="7" height="7" />
</svg>
<span class="sidebar-link-text">Dashboard</span>
</a>
<a href="#" class="sidebar-link">
<svg
class="sidebar-link-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M22 12h-6l-2 3h-4l-2-3H2" />
<path
d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"
/>
</svg>
<span class="sidebar-link-text">Inbox</span>
<span class="sidebar-link-meta badge is-neutral">12</span>
</a>
<a href="#" class="sidebar-link">
<svg
class="sidebar-link-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<circle cx="12" cy="12" r="3" />
<path
d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"
/>
</svg>
<span class="sidebar-link-text">Settings</span>
</a>
</nav>
<footer>
<a href="#" class="sidebar-link">
<svg
class="sidebar-link-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<circle cx="12" cy="8" r="4" />
<path d="M6 21v-2a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v2" />
</svg>
<span class="sidebar-link-text">octetic</span>
</a>
</footer>
</aside>
Without the inline-end border
<aside class="sidebar no-border">
<nav class="sidebar-nav" aria-label="Secondary">
<a href="#" class="sidebar-link" aria-current="page">
<svg
class="sidebar-link-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<circle cx="12" cy="12" r="10" />
</svg>
<span class="sidebar-link-text">Summary</span>
</a>
<a href="#" class="sidebar-link">
<svg
class="sidebar-link-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M3 3h18v18H3z" />
</svg>
<span class="sidebar-link-text">Details</span>
</a>
</nav>
</aside>
Collapsed rail
<aside class="sidebar" data-collapsed>
<nav class="sidebar-nav" aria-label="Primary">
<a href="#" class="sidebar-link" aria-current="page" aria-label="Dashboard">
<svg
class="sidebar-link-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<rect x="3" y="3" width="7" height="7" />
<rect x="14" y="3" width="7" height="7" />
<rect x="3" y="14" width="7" height="7" />
<rect x="14" y="14" width="7" height="7" />
</svg>
<span class="sidebar-link-text">Dashboard</span>
</a>
<a href="#" class="sidebar-link" aria-label="Inbox">
<svg
class="sidebar-link-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M22 12h-6l-2 3h-4l-2-3H2" />
<path
d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"
/>
</svg>
<span class="sidebar-link-text">Inbox</span>
</a>
<a href="#" class="sidebar-link" aria-label="Settings">
<svg
class="sidebar-link-icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<circle cx="12" cy="12" r="3" />
<path
d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"
/>
</svg>
<span class="sidebar-link-text">Settings</span>
</a>
</nav>
</aside>
Mobile toggle
<button
class="sidebar-toggle"
type="button"
commandfor="mobile-drawer"
command="show-modal"
aria-label="Open navigation"
>
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<line x1="3" y1="6" x2="21" y2="6" />
<line x1="3" y1="12" x2="21" y2="12" />
<line x1="3" y1="18" x2="21" y2="18" />
</svg>
<span>Menu</span>
</button>
Source comments
Sidebar -- fixed-width side panel.
Structure -- semantic HTML carries the regions, no slot classes:
<aside class="sidebar">
<header> <-- optional top region; bordered separator
<strong>Acme</strong>
</header>
<nav class="sidebar-nav">...</nav>
<footer> <-- optional bottom region; bordered separator
...
</footer>
</aside>
Direct-child <header> and <footer> pick up the region chrome
(padding, separator border, flex-shrink: 0). Position-agnostic --
unlike card and popover, the styling here isn't geometry-sensitive
(no full-bleed math), so first-/last-child constraints would only
add a footgun without a load-bearing reason.
Responsive:
Below 64rem (mobile): the sidebar is hidden and .sidebar-toggle is
revealed. Consumers wire the toggle to a <brio-drawer> that holds a
copy of the sidebar-nav for mobile navigation.
Collapsed mode:
[data-collapsed] on the panel thins it to an icon rail. The width
remaps to --sidebar-collapsed-width and the nav drops its labels
(see sidebar-nav.css). A consumer override of --sidebar-width
wins the cascade, so when you remap the expanded width, scope the
override to :not([data-collapsed]) to keep the rail. The width
transition ships here on purpose: the collapse is a user-initiated
change of layout, not a hover state, so it uses
--transition-normal and prefers-reduced-motion flattens it at the
token level (P13). It interpolates at all because --sidebar-width
is @property-registered (brio.css).
Reference
Source: src/css/sidebar.css
.sidebar
| Class | Kind | Description |
.no-border | opt-out | Removes the inline-end border |
| Slot | Description |
> header | The header section at the top of a sidebar |
> footer | The footer secton at the bottom of a sidebar |
.sidebar-toggle | Mobile toggle -- hidden on desktop, revealed below 64rem in place of the hidden sidebar. Styled like a minimal button; consumers wire the open action with commandfor targeting a <brio-drawer> by ID. |
| Token | Default | Description |
--sidebar-width | 16rem | Width of the sidebar panel |
--sidebar-bg | var(--color-surface) | Background color for the sidebar |
--sidebar-border-color | var(--color-border-subtle) | Border color of the panel's inline-end edge |
--sidebar-border-width | var(--border-width-default) | Border width of the panel's inline-end edge |
--sidebar-link-font-size | var(--ui-font-size-sm) | Font size for sidebar-link rows inside the panel |
--sidebar-collapsed-width | 3rem | Width of the panel while [data-collapsed] is set |
--sidebar-header-border-color | var(--color-border-subtle) | Border color for the header region separator |
--sidebar-footer-border-color | var(--color-border-subtle) | Border color for the footer region separator |