relay Design System
イントロダクション
  • MCP サーバー
  • 取り組み
  • 品質評価
  • 監査ログ
  • リリースログ
Foundations
  • 色
  • タイポグラフィ
  • レイアウト
  • エフェクト
  • アイコン
  • アセット
Components
  • ボタン
  • アイコンボタン
  • ボタングループ
  • トグルボタングループ
  • ラベルコントロール
  • インプット
  • サーチインプット
  • タグ
  • タグインプット
  • セレクター
  • マルチセレクター
  • テキストエリア
  • チェックボックス
  • ラジオ
  • フィルターチップ
  • タブ
  • テーブル
  • シンプルテーブル
  • カード
  • バッジ
  • アラート
  • インラインメッセージ
  • リンクテキスト
  • パンくずリスト
  • メニュー
  • アクションメニュー
  • ページネーション
  • ステッパー
  • モーダル
  • ツールチップ
  • スケルトン
  • トグルスイッチ
  • アコーディオン
  • ページシェル
Patterns
  • フォーム
  • フィードバック
  1. ホーム
  2. Components
  3. メニュー

メニュー

component

縦に項目を並べる汎用メニューです。いま開いているページを示しながら移動できるナビゲーション(サイドナビ)にも、設定・ログアウトなどの操作を並べるアクションメニューにも使えます。幅は親要素で決めます(サイドナビ用途は w-70 = 280px が目安)。

項目の状態

default / hover / focus / current。hover はニュートラル(背景 neutral/100)、current は primary(背景 primary/50 + 文字 primary/600)。太さは全状態 bold 共通。primary は「現在地」の意味に予約

default
  • メニュー項目
hover
  • メニュー項目
focus
  • メニュー項目
current
  • メニュー項目

サイズ

md(既定、padding 12)/ sm(.menu-item-sm、padding 8)。sm は項目数が多く密度を上げたいナビ(ドキュメントのサイドナビ等)専用

md(既定)
  • メニュー項目
  • メニュー項目
sm
  • メニュー項目
  • メニュー項目

使用例: ナビゲーション(サイドナビ)

nav 要素で包み、現在地に aria-current="page"。グループは .menu-divider で区切る。外部リンク等の末尾装飾アイコンは .menu-item-trailing(16px・右端寄せ)

  • マイページTOP
  • 財務情報購入履歴
  • プレミアム会員登録
  • おすすめ案件設定

  • 基本情報(本人確認)
  • アカウント設定
  • ヘルプセンター

使用例: 見出し付きグループ

項目が多く分類名があると探しやすいときは .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

要素の役割を分ける
Good
  • 案件一覧(ページ遷移)

ページ遷移は <a href>、その場の操作は <button>。SR に役割が正しく伝わり、遷移は新規タブ・右クリックも効く。

<a class="menu-item" href="…">案件一覧</a>
<button type="button" class="menu-item">ログアウト</button>
Don't

遷移を button にしない。役割が「ボタン」になり、遷移手段(新規タブ等)が失われる。

<button type="button" class="menu-item">案件一覧</button>

アイコンの有無はグループ内で揃える

視線と整列
Good
  • マイページ
  • アカウント設定

同じグループは全項目にアイコンを付ける(または全て無し)。ラベル開始位置が揃い、走査しやすい。

<a class="menu-item"><svg class="icon">…</svg>マイページ</a>
<a class="menu-item"><svg class="icon">…</svg>アカウント設定</a>
Don't
  • マイページ
  • アカウント設定

一部だけアイコンを付けると、ラベル開始位置がずれて視線が乱れる。

<a class="menu-item"><svg class="icon">…</svg>マイページ</a>
<a class="menu-item">アカウント設定</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 色の使用
Good
  • マイページ
  • アカウント設定

aria-current="page" を付けると、背景色+文字色に加え SR が「現在のページ」と読む。

<a class="menu-item" aria-current="page">マイページ</a>
Don't
  • マイページ
  • アカウント設定

aria-current が無いと DS の現在地スタイルも当たらず、視覚的にも SR 的にも現在地が示されない。

<a class="menu-item" href="…">マイページ</a>  <!-- aria-current なし -->

キーボードだけで操作する(試せます)

達成基準:WCAG 2.1.1 キーボード

下のメニューをクリック、または Tab でフォーカスしてから ↑ ↓ を押すと、項目間をフォーカスが移動します。

  • マイページTOP
  • プロフィール
  • 書類
  • お知らせ
TabShift+Tab
メニューに入る/各項目へ移動(全項目が Tab 順に残る)
↑↓
前後の項目へフォーカスを移す(端でループ)
HomeEnd
先頭/末尾の項目へ一気に移動
Enter
リンクを遷移/ボタンを実行

矢印キー移動は小さな JS で有効化します(Tab / Enter は JS なしでも動作)。実装例はカタログの catalog.js の Menu ハンドラ。

関連する達成基準(WCAG 2.2)

1.3.1 情報及び関係性 ・ 1.4.1 色の使用 ・ 2.1.1 キーボード ・ 2.4.4 リンクの目的 ・ 2.4.7 フォーカスの可視化 ・ 4.1.2 名前・役割・値