画面左端(または右端)に固定された垂直ナビゲーション。管理画面・ダッシュボード・ドキュメントサイトなど、階層が深くメニュー数が多いアプリで「常に全メニューを見せておく」ために使う。モバイルでは折りたたんで Sheet / Drawer として出現するパターンが標準。
この記事を読むと、SidebarとTop nav・Menubarの使い分け・折りたたみ(Collapsed)設計・Active状態の表現・キーボードナビゲーションの実装基準が自分でできるようになります。
1. UI例(Preview / Live)
実装で見る(GunjoUI)
この部品を、デザインシステム GUNJO の実装で確かめられます。
2. 定義(Definition)
画面の左端(まれに右端)に固定された垂直方向のナビゲーションコンポーネント。アプリ全体のメニューを常時表示し、どのページからでも任意のセクションに直接移動できる。グループ化・折りたたみ・階層表示に対応し、メニュー数が多い複雑なアプリに適している。
Top nav との違い:Top nav は水平方向・項目数が少ない・コンテンツ幅を最大化する場面向け。Sidebar は垂直方向・項目数が多い・常時メニューを見せる管理画面向け。
Sheet / Drawer との違い:Sheet はオーバーレイで一時的に表示するパネル。Sidebar は常時表示の固定ナビゲーション。モバイルではSidebarをSheet として出現させるパターンが一般的。
3. 使い分け(When to use / When NOT to use)
3.1 When to use
- 管理画面・ダッシュボード・SaaSアプリなど、メニュー項目が多く階層が深いアプリ
- ユーザーが複数のセクション間を頻繁に行き来する場面
- 現在地と全体構造を常時把握させたい場面
3.2 When NOT to use
- メニュー項目が5つ以下の浅いサイト → Top nav の方がシンプル
- コンテンツの幅が最重要なドキュメントページ・LP → Sidebar がコンテンツ領域を圧迫する
- モバイルのみのアプリ → Bottom nav / App rail の方がユーザーの親指に近い
3.3 代替UI(Alternatives)
- 項目数が少ない →
Top nav(水平ナビゲーションバー) - モバイルメイン →
App rail(左端のアイコンのみナビ)/Bottom nav - 一時的なメニュー →
Sheet / Drawer - コンテキスト依存のナビゲーション →
Tabs
4. 設計判断の核(Decision Principles)
Sidebar に表示するメニューは「アプリの全セクション」——ページ固有のアクションはSidebarに入れない。
判断の優先順位:① メニュー数と階層 → ② Active状態の表現 → ③ モバイル対応 → ④ 折りたたみの必要性
- Active状態の明示:現在地のメニュー項目は必ず他と視覚的に区別できるスタイル(背景色・太字・左ボーダーなど)にし、
aria-current="page"を付与する - 階層は2段まで:3段以上の深い階層はSidebar内で表現せず、ページ内のサブナビやBreadcrumbで補完する
- 折りたたみ(Collapsed)は便宜上の補助:Collapsed時はアイコンのみ表示し、ホバーでTooltipを表示する。アイコンなしの項目にはCollapsedは使わない
- モバイルでは必ずSheet化:Sidebarをモバイルでそのまま表示すると画面を圧迫する。
md:ブレークポイント以上でのみ表示し、モバイルではハンバーガーメニュー→Sheet で代替する
5. 状態設計(States)
5.1 必須状態(Required)
- Default:全メニュー項目が表示され、Active 項目が強調表示されている
- Active(現在地):背景色・太字・左ボーダーなどで他と区別。
aria-current="page"を付与 - Hover:ホバー時に背景色変化でクリッカブルを示す
- Focus:フォーカスリングを表示(省略不可)
5.2 条件付き状態(Conditional)
- Collapsed:アイコンのみ表示。ホバー時にラベルをTooltipで表示する
- Expanded group:折りたたみグループが開いた状態。子メニューが表示される
- Disabled item:権限がなく選択できない項目。理由をTooltipで示す
5.3 State Gallery
| 状態 | 必須 | 何を伝えるか |
|---|---|---|
| Default | ✅ | 全ナビゲーション項目と全体構造 |
| Active | ✅ | 今どのページにいるかを常時表示 |
| Hover | ✅ | この項目でナビゲートできることを示す |
| Focus | ✅ | キーボードユーザーに今どの項目にいるかを示す |
| Collapsed | — | 画面幅を節約しながらナビゲーションを維持する |
| Disabled | — | 権限がなくアクセスできないことを示す |
6. バリエーション設計(Variants)
Sidebarのバリアントは「展開幅」と「グループ構造の有無」で決まる。
| バリアント | 目的 |
|---|---|
| Expanded(展開) | アイコン+ラベルを常時表示。標準スタイル |
| Collapsed(折りたたみ) | アイコンのみ表示。コンテンツ幅を広げたい場合 |
| Grouped(グループあり) | アコーディオン形式でグループを折りたたむ。項目数が多い場合 |
| Floating / Overlay | コンテンツの上にオーバーレイで表示。モバイルのSheet化パターン |
禁止パターン:Collapsed 状態でアイコンなしの項目を使う → ラベルが消えた時に何の項目か判別不能になる。
7. パターン集(Good / Bad / How to fix)
7.0 よく崩れる設計パターン(3つ)
- Active状態の欠落:全メニュー項目が同じスタイルで、現在地がどこか分からない
- モバイル未対応:デスクトップ幅のSidebarをモバイルでもそのまま表示し、コンテンツ領域がほぼゼロになる
- 階層が深すぎる:3〜4段の入れ子メニューをSidebar内で展開し、メニューだけで画面が埋まる
7.1 Bad(典型3つ)
- 全項目が同色・同ウェイトで Active 状態が分からず「今どこにいるか」が把握できない
- モバイルでSidebarが固定表示のままでコンテンツ幅が100px未満になっている
- 5段階の入れ子をSidebar内で全展開し、スクロールしないと全項目を確認できない
7.2 Good(対になる3つ)
- Active項目に
bg-blue-100・font-medium・左ボーダーを付与し、aria-current="page"を設定する md:flex hiddenでモバイルではSidebarを非表示にし、ハンバーガーボタン→Sheet で代替する- 階層は最大2段に制限し、3段以上の構造はページ内のサブナビかBreadcrumbで表現する
7.3 How to fix(手順)
- Active項目の
classNameに条件分岐を加え、背景色・太字・左ボーダーなどで強調する aria-current="page"を現在のページに対応する<a>または<button>に付与する<nav aria-label="サイドナビゲーション">でラップしてランドマークとして認識させる- モバイルブレークポイントでSidebarを非表示にし、Sheet への切り替えロジックを実装する
8. ルール(Must / Better)
Must(守らないと壊れる)
Better(品質が跳ねる)
9. アクセシビリティ要件(必須)
Keyboard
Tabで各リンク・ボタンにフォーカスでき、Enter/Spaceでアクティベートできること- グループの展開ボタンは
Enter/Spaceで開閉できること
Focus
- フォーカスリングはSidebarの背景色と4.5:1以上のコントラストを持つこと
Screen Reader
<nav aria-label="サイドナビゲーション">でランドマーク登録する- Active項目に
aria-current="page"を付与する - グループ展開ボタンに
aria-expanded="true/false"を付与する - Collapsed 状態でラベルが非表示の場合、
aria-labelでラベルを補完する
<!-- 基本パターン -->
<nav aria-label="サイドナビゲーション">
<ul role="list">
<li>
<a href="/dashboard" aria-current="page">
🏠 ダッシュボード
</a>
</li>
<li>
<button aria-expanded="true">
📊 アナリティクス
</button>
<ul role="list">
<li><a href="/analytics/overview">概要</a></li>
</ul>
</li>
</ul>
</nav>
Touch / Pointer
- 各ナビ項目のタップ領域は44px以上の高さを確保する
- モバイルではSidebarを非表示にして Sheet / Drawer で代替する
Contrast / Readability
- Active項目のテキストは背景色と4.5:1以上のコントラスト比を確保する
- 非Active項目のテキストも4.5:1以上を確保する
10. 実装メモ(Implementation Notes)
- shadcn/ui には
Sidebarコンポーネントが含まれており、Collapsed / Expanded / Mobile Sheet の切り替えが実装済み。新規プロジェクトでは積極的に活用する - Next.js App Router では
usePathname()でパスを取得し、各ナビ項目のパスと比較してaria-currentと Active スタイルを動的に設定する - Sidebar の幅は CSS変数(
--sidebar-width: 240px)として定義し、コンテンツエリアのmargin-leftと同期させると、Collapsed 時のアニメーションが一箇所で管理できる
11. 関連リンク
- 関連するUIデザイン原則: ナビゲーション設計 (Navigation Design), 情報設計 (Information Architecture), 迷わせない情報設計 (Findability)
- 用語集(定義): 情報アーキテクチャ (Information Architecture), ナビゲーション・ファティーグ (Navigation Fatigue)
- 関連するUIコンポーネント(横): Breadcrumb(パンくずリスト), Tabs(タブ), Sheet / Drawer(ドロワー / シート)
12. まとめ
Sidebarの設計は「Active状態の明示」と「モバイル対応」の2点が最低ラインです。迷ったら 4. 設計判断の核 に戻り、Active項目のスタイル・aria-current の付与・モバイルでのSheet化の3点を確認してください。階層は2段まで、それ以上はBreadcrumbやページ内サブナビで補完——Sidebarを深くするのではなくフラットに保つことが、ナビゲーション疲れを防ぐ最短の設計判断です。