Component Docs Sidenav
component-docs-sidenav — Design Rationale
ai_consumption_hint: Left navigation sidebar for product-documentation pages.
Use class="docs-sidenav" on the <nav> element with aria-label="Documentation navigation".
Category sections use native <details>/<summary> — no JS needed for expand/collapse.
Active link: add class="docs-sidenav__link is-active" and aria-current="page".
Server must set open attribute on the <details> whose category contains the active page.
Width token: --sidenav-w: 256px. Hidden below 1024px via display: none.
Origin: project-knowledge DESIGN-COMPONENT (2026-06-01) · source_commit: 914cd836
Recipe: components/docs-sidenav/guide.md
What problem this solves
Product-documentation surfaces need persistent left navigation that shows the full content hierarchy at a glance, lets readers jump across categories without returning to a homepage, and does not require JavaScript for basic open/close behaviour.
IBM Carbon's Side Nav was evaluated and rejected: it carries icon slots, multi-level nesting, and 256px fixed-rail width designed for enterprise app shells. The corpus is a documentation wiki without per-article icon assignments. Carbon's pattern would impose icon maintenance overhead for no reader benefit.
The pattern observed across Stripe docs, Vercel docs, and Cloudflare docs (all surveyed
2026-06-01) is: uppercase category labels with article link lists inside collapsible
sections. The implementation at app-mediakit-knowledge commit 914cd836 follows
this pattern.
Key decisions
<details>/<summary> over JS accordion. Native elements work without JS,
are keyboard-navigable by default (Enter/Space), and carry correct implicit ARIA
semantics (aria-expanded is managed by the browser). The chevron animation is
CSS-only via the [open] attribute selector — no state management code.
--sidenav-w: 256px as a CSS token. Width extracted to a custom property so
the shell grid and any future sidenav-aware components (mobile drawer, etc.) share
the same measurement without hardcoding.
Active category auto-expanded server-side. Server adds open attribute on
the <details> whose category matches the current article's category slug. Avoids
the flash-of-collapsed-nav that JS-based lazy expansion causes on initial page load.
No icons. Stripe, Vercel, and Cloudflare docs all include icon slots for brand identity. Omitted here: content corpus is a documentation wiki; icons would require per-article assignments not in the current content schema.
display: none below 1024px, not a drawer. No sidenav-exclusive content —
all articles are reachable via breadcrumb. Hiding rather than collapsing to a
drawer keeps the mobile layout simple. A drawer pattern is a future option if
content volume grows past breadcrumb navigability.
Token dependencies
--sidenav-w— column width (defined in this component; consumed by.shellgrid)--header-h— sticky top offset (defined in wiki chrome)--fg-1,--fg-2,--fg-3,--fg-4— foreground scale--link/--navyfallback — active link and border accent--bg-hover,--bg-subtle— hover and active backgrounds--rule— right-border and divider--font-display/--font-bodyfallback — category label typeface
Open questions
- Mobile drawer.
display: nonebelow 1024px is the current decision. A hamburger-triggered drawer would require an additional component and JS state. Deferred pending content volume. - Hierarchy depth. One category level is the current maximum. Nested categories
would require a different pattern (recursive
<details>or a new component). Deferred pending content structure decision.
Important Information
Design System disclosure
This site provides open-source design tokens, documentation, and self-hostable software published by Woodfine Capital Projects Inc. Information here is for general reference only and does not constitute an offer, warranty, or a guarantee of fitness for any particular purpose. Statements regarding planned, intended, or targeted future features are forward-looking and subject to change without notice; they are not undertaken to be updated except as required by law.