メニュー
component縦に項目を並べる汎用メニューです。いま開いているページを示しながら移動できるナビゲーション(サイドナビ)にも、設定・ログアウトなどの操作を並べるアクションメニューにも使えます。幅は親要素で決めます(サイドナビ用途は w-70 = 280px が目安)。
項目の状態
default / hover / focus / current。hover はニュートラル(背景 neutral/100)、current は primary(背景 primary/50 + 文字 primary/600)。太さは全状態 bold 共通。primary は「現在地」の意味に予約
サイズ
md(既定、padding 12)/ sm(.menu-item-sm、padding 8)。sm は項目数が多く密度を上げたいナビ(ドキュメントのサイドナビ等)専用
使用例: ナビゲーション(サイドナビ)
nav 要素で包み、現在地に aria-current="page"。グループは .menu-divider で区切る。外部リンク等の末尾装飾アイコンは .menu-item-trailing(16px・右端寄せ)
使用例: 見出し付きグループ
項目が多く分類名があると探しやすいときは .menu-section で見出し .menu-group-title(h2〜h6)と .menu-group をまとめ、ul に aria-labelledby。見出しを付けるなら全グループに付ける。区切り線は任意
使用例: アクションメニュー
操作の項目は button 要素で書く(遷移は a)。ナビゲーションではないので nav では包まない。左アイコンは任意(付けるなら同じグループ内で有無を揃える)
機能
このコンポーネントの用途
縦に項目を並べる汎用メニュー。現在地を示しながら階層を移動するナビゲーション
(マイページのサイドナビ等)と、操作を並べるアクションメニューの両方に使う。
設定画面のセクション移動(プロフィール / 通知 / セキュリティ等)は「独立した画面 + menu」
で作る(各セクションはフォームと URL を持つ画面なので、tab で同一ページに畳まない)。
サイト階層のパス表示は breadcrumb、URL を持たない同一画面内の視点切替は tab。
ボタンを押して開くポップアップの操作メニュー(三点メニュー等)は action-menu(項目は menu-item を再利用)。
使用法
推奨される使い方と、やりがちな NG パターン
OK
- ✓ナビ用途は nav 要素で包んで aria-label を付け、現在地に aria-current="page" を付ける。
- ✓項目は遷移なら a、操作(ログアウト等)なら button を使う。どちらも下線なし(項目形状のため「常に下線」原則の例外)。
- ✓左アイコンは任意。付けるなら同じグループ内では有無を揃える(テキストの頭が揃わなくなるため)。
- ✓外部リンク等の末尾装飾アイコンは menu-item-trailing(16px・右端寄せ)。左アイコンの 20px と混同しない。
- ✓グループは menu-group、区切りは menu-divider。幅は親要素で決める(サイドナビは w-70 = 280px 目安)。
- ✓項目が多く分類名があると探しやすいときは、menu-section で見出し(menu-group-title)と menu-group を まとめる。見出しは h2〜h6 の実際の見出し要素にし(レベルはページの見出し階層に合わせる)、 ul に aria-labelledby で見出しの id を結ぶ。section 間の区切り線は任意(menu-divider を挟む)。
- ✓項目数が多く密度を上げたいナビ(ドキュメントのサイドナビ等)は menu-item-sm。通常は md(既定)のまま。
NG
- ✕現在地をクラスだけで示さない → aria-current="page" を付ける。
- ✕横並びのコンテンツ切替に流用しない → tab。
- ✕グループ見出しを div / span や menu-item で作らない → menu-group-title を見出し要素に付ける。 見出しはクリックできない分類名であり、項目(遷移・操作)と混ぜない。
- ✕一部のグループだけに見出しを付けない → 付けるなら全グループに付ける(無見出しのグループが 直前の見出しに属して見える)。
- ✕操作項目に a を使わない → 遷移は a / 実行は button。
- ✕一部の項目だけにアイコンを付けない → 全項目に付けるか全項目で外す。混在するとラベルの 開始位置がずれて視線が乱れる。
遷移は a・操作は button
要素の役割を分ける
ページ遷移は <a href>、その場の操作は <button>。SR に役割が正しく伝わり、遷移は新規タブ・右クリックも効く。
<a class="menu-item" href="…">案件一覧</a> <button type="button" class="menu-item">ログアウト</button>
遷移を button にしない。役割が「ボタン」になり、遷移手段(新規タブ等)が失われる。
<button type="button" class="menu-item">案件一覧</button>
アイコンの有無はグループ内で揃える
視線と整列同じグループは全項目にアイコンを付ける(または全て無し)。ラベル開始位置が揃い、走査しやすい。
<a class="menu-item"><svg class="icon">…</svg>マイページ</a> <a class="menu-item"><svg class="icon">…</svg>アカウント設定</a>
メニューのアクセシビリティ
relay のメニューは ネイティブ nav + a / button ベースです(ARIA メニューウィジェット role=menu ではありません)。キーボードは Tab / Enter で操作でき、加えて上下矢印キーでも項目間を移動できます(roving tabindex は使わず全項目を Tab 順に残したままの追加操作)。WCAG 2.2 全基準は アクセシビリティ ページを参照。
期待される配慮
Presentation / Adaptability / Interaction / Assistive Technology
現在地は aria-current="page" による背景色+文字色で示す(太さは全項目 bold で共通)。左アイコンは装飾、区切りは menu-divider でグループ化。
幅は親要素で決まり、リフローで縦積みに崩れても機能を失わない。文字は rem / トークンで拡大に追従。
Tab で各項目へ、Enter で遷移/実行。加えて ↑ ↓ でも項目間を移動できる(JS 付与時。Tab 順は保つ)。フォーカスリングで位置が分かる。
nav は aria-label でランドマーク名を持ち、各項目は role=link / button として、現在地は「現在のページ」として読まれる。
DS が担保する機能
追加実装なしで満たされる
- ✓ネイティブ
nav+a/buttonベース — 役割・名前・状態が標準で確立 - ✓
aria-current="page"で現在地を支援技術に伝える(見た目は背景色+文字色) - ✓フォーカスリング
--shadow-focus-ring(:focus-visible) - ✓末尾装飾アイコン
menu-item-trailingはaria-hidden前提の設計 - ✓テキスト色は
fg-*ロールでコントラストを確保
実装時の必須対応
プロダクト側で担保する
- !ナビは
<nav aria-label="…">で包む。複数ある場合は固有のラベルを付ける - !現在地に
aria-current="page"(色だけに頼らない) - !グループ見出しは
.menu-group-titleを h2〜h6 の見出し要素に付け、ul にaria-labelledbyで結ぶ - !遷移は
<a>、操作は<button>と要素で役割を分ける - !装飾アイコンは
aria-hidden="true"、別タブで開くリンクは手がかりと説明を添える
テスト方法
キーボード / スクリーンリーダー / 自動チェック
| キー | 動作 |
|---|---|
| Tab / Shift+Tab | 各項目へ移動する(全項目が Tab 順に残る) |
| ↑ / ↓ | 前後の項目へフォーカスを移す(端でループ・JS 付与時) |
| Home / End | 先頭 / 末尾の項目へ移動する(JS 付与時) |
| Enter | リンクを遷移 / ボタンを実行する |
- SRランドマーク「ナビゲーション: <ラベル>」、現在地は「現在のページ」、各項目のラベルが読まれる
- 操作Tab で全項目を辿れる。JS を付与すると ↑ ↓ / Home / End でも移動できる(Tab 順は保つ)
- 自動axe / Lighthouse で nav ラベル・
aria-current・リンク名・コントラストを確認
現在地は aria-current="page"
達成基準:WCAG 4.1.2 名前・役割・値 / 1.4.1 色の使用
aria-current="page" を付けると、背景色+文字色に加え SR が「現在のページ」と読む。
<a class="menu-item" aria-current="page">マイページ</a>
aria-current が無いと DS の現在地スタイルも当たらず、視覚的にも SR 的にも現在地が示されない。
<a class="menu-item" href="…">マイページ</a> <!-- aria-current なし -->
キーボードだけで操作する(試せます)
達成基準:WCAG 2.1.1 キーボード下のメニューをクリック、または Tab でフォーカスしてから ↑ ↓ を押すと、項目間をフォーカスが移動します。
- TabShift+Tab
- メニューに入る/各項目へ移動(全項目が Tab 順に残る)
- ↑↓
- 前後の項目へフォーカスを移す(端でループ)
- HomeEnd
- 先頭/末尾の項目へ一気に移動
- Enter
- リンクを遷移/ボタンを実行
矢印キー移動は小さな JS で有効化します(Tab / Enter は JS なしでも動作)。実装例はカタログの catalog.js の Menu ハンドラ。