UIXHERO

Dropdown Menu(ドロップダウンメニュー)

トリガー要素をクリック/ホバーすると展開するメニューUIコンポーネント。Context MenuやSelectとの使い分け・フォーカス管理・サブメニュー設計・ARIA menuパターンの実装を解説する。

2026年3月2日
更新: 2026年8月28日
28
by Dengen Yosho(DGYS)

ボタンやアバターなどのトリガー要素をクリックすると展開し、アクション・リンク・サブを提供するUIコンポーネント。「三点リーダー(⋯)」メニュー・ユーザーアバターメニュー・ナビゲーションの「もっと見る」など、画面スペースを節約しながら複数のアクションを格納する用途で頻繁に使われる。

この記事を読むと、DropdownとSelect・Context Menuの使い分け・ARIA role="menu" パターン・フォーカス管理(開いたら最初の項目にフォーカス)・サブメニューとキーボードナビゲーションが自分でできるようになります。


1. UI例(Preview / Live)

実装で見る(GunjoUI)

この部品を、デザインシステム GUNJO の実装で確かめられます。

2. 定義(Definition)

トリガー要素(ボタン・アバター・三点リーダーなど)をクリックすると展開し、アクション・リンク・設定項目の一覧を表示するコンポーネント。「メニュー」として機能するため role="menu"role="menuitem" の意味論的マークアップが必要。

SelectとDropdown Menuの違い:Selectは「フォームの入力値を選ぶ(値が変わる)」。Dropdown Menuは「アクションを実行する(コマンドの一覧)」。技術的には似た実装でも、意味論は異なる—Select は role="combobox" / role="listbox"、Dropdown Menu は role="menu" / role="menuitem" を使う。

Context MenuとDropdown Menuの違い Menuは「右クリック(長押し)で表示するコンテキスト依存のメニュー」。Dropdown MenuはUI上のトリガーをクリックして明示的に開くメニュー。


3. 使い分け(When to use / When NOT to use)

3.1 When to use

  • 1つのトリガーから複数のアクションを提供したい場合(編集・複製・削除など)
  • 画面スペースを節約してアクションを折りたたむ必要がある場合(三点リーダーメニュー)
  • ユーザーアカウントメニュー(アバタークリックでプロフィール・設定・ログアウト)
  • ナビゲーションバーの「もっと見る」メニュー

3.2 When NOT to use

  • フォームで値を選ぶ → Select(または Combobox)を使う
  • 操作が1つだけ → 直接ボタンを置く
  • 全メニュー項目を常時表示できるスペースがある → 常時表示のほうが発見しやすい

3.3 代替UI(Alternatives)

  • フォームの選択肢 → Select
  • コンテンツの右クリックメニュー → Context Menu
  • 複雑なアクションの検索・実行 → Command Palette
  • 簡単なPopover

4. 設計判断の核(Decision Principles)

Dropdown Menuの核はフォーカス管理——開いたら最初の項目にフォーカスを移し、Escで閉じてトリガーにフォーカスを戻す。この動作がないとキーボードユーザーはメニューに閉じ込められる。

判断の優先順位:① フォーカス管理 → ② 開閉ARの付与 → ③ 項目のグループ化 → ④ 破壊的アクションの分離

  • 開いたら最初のメニュー項目にフォーカスを移すrole="menu" を持つ要素が開いたら、最初の role="menuitem" に自動的にフォーカスする。そうしないとキーボードユーザーはメニューの存在に気づかない
  • Escで閉じてトリガーにフォーカスを戻す:Escキーでメニューを閉じた後、⌘K のように開いたボタンにフォーカスを戻す。これがないと次のTabキー操作で意図しない場所にジャンプする
  • 破壊的アクションはSeparatorで区切り赤色で示す:「削除する」などの取り消し不能な操作はメニュー下部にSeparatorで分離し、赤色テキストで示す。ユーザーが誤って実行するリスクを下げる
  • 三点リーダーボタンには aria-label が必須:アイコンのみのトリガーボタン()は、スクリーンリーダーが何のボタンか読めない。aria-label="記事のオプション" のように具体的に説明する

5. 状態設計(States)

5.1 必須状態(Required)

  • Closed(閉じた状態):トリガーボタンのみ表示
  • Open(展開した状態):メニューが表示され、最初の項目にフォーカス

5.2 条件付き状態(Conditional)

  • Hover(項目にカーソル):ハイライト表示
  • Focus(キーボードでの選択中):フォーカスリング表示
  • Disabled(無効化された項目):グレーアウト、aria-disabled="true"
  • Checked(チェック可能な項目)role="menuitemcheckbox" + チェックアイコン
状態必須何を伝えるか
Closed展開可能(aria-haspopup で伝える)
Openメニュー項目の一覧
Item Hover / Focus選択可能・選択中
Item Disabledこの操作は現在使えない
Item Checkedこの設定がオンになっている

6. バリエーション設計(Variants)

用途によってメニューの内容構成が変わる。

バリアント内容典型的なトリガー
アクションメニュー編集・複製・削除などのアクション三点リーダー(⋯)
ユーザーメニュープロフィール・設定・ログアウトアバター
ナビゲーションメニューページリンクの一覧「もっと見る」ボタン
設定メニュートグル可能な設定項目設定アイコン

禁止パターン:フォームの <select> の代替として Dropdown Menu を使う → <select> が意味論的に正しく、フォーム送信・モバイルのUIとの統合が壊れる。フォームにはSelectコンポーネントを使う。


7. パターン集(Good / Bad / How to fix)

7.0 よく崩れる設計パターン(3つ)

  • フォーカス管理なし:メニューが開いてもフォーカスが移らず、キーボードユーザーがメニュー項目にたどり着けない
  • Escで閉じた後のフォーカス喪失:Escで閉じた後フォーカスが行方不明になり、次のTabキーで意図しない場所にジャンプする
  • 三点リーダーボタンに aria-label がない:スクリーンリーダーが「ボタン」としか読み上げず、何のメニューか分からない

7.1 Bad(典型3つ)

  • メニューが開いてもフォーカスが入力フィールドに残ったまま、↓キーを押しても何も選択されない
  • Escキーのイベントを実装しておらず、メニューを閉じるにはEsc以外の手段(Tabで抜けるなど)が必要
  • <button>⋯</button> だけでラベルなし、スクリーンリーダーが「ボタン」としか読み上げない

7.2 Good(対になる3つ)

  • メニューが開いたら useEffect で最初の [role="menuitem"]focus() を呼ぶ
  • onKeyDownEscape を実装し、メニューを閉じた後 triggerRef.current?.focus() でトリガーにフォーカスを戻す
  • <button aria-label="記事『Button』のオプション">⋯</button> のようにを含めた aria-label を付与する

7.3 How to fix(手順)

  1. useRef でトリガーボタンの参照を保持し、onClose 時に triggerRef.current?.focus() を呼ぶ
  2. メニューが開いた時(open === true)の useEffectmenuRef.current?.querySelector('[role="menuitem"]')?.focus() を呼ぶ
  3. onKeyDown(項目移動)・Enter(実行)・Escape(閉じる)・Home(最初に移動)・End(最後に移動)を実装する
  4. 三点リーダーなどアイコンのみのボタンに aria-label を追加する

7.4 GUNJO 実装で見る(Bad / Good)

同じ GUNJO の DropdownMenu を、崩れた使い方と正しい使い方で


8. ルール(Must / Better)

Must(守らないと壊れる)

Better(品質が跳ねる)


9. アクセシビリティ要件(必須)

Keyboard

  • Enter / Space でトリガーボタンをクリックしてメニューを開く
  • / でメニュー項目を移動(最後の項目の↓で最初に戻るループも推奨)
  • Enter で選択中の項目を実行してメニューを閉じる
  • Escape でメニューを閉じてトリガーにフォーカスを戻す
  • Home / End でリストの最初・最後に移動する

Focus

  • メニューが開いたら最初の menuitem にフォーカスを移す
  • 閉じた後はトリガーボタンにフォーカスを戻す
  • メニュー外へのTabフォーカスを許容(は不要、Tabで自然にメニューを閉じるのも可)

Screen Reader

<!-- トリガーボタン -->
<button
  aria-haspopup="menu"
  aria-expanded="true"
  aria-controls="user-menu"
>
  ユーザーメニューを開く
</button>

<!-- メニュー -->
<div id="user-menu" role="menu" aria-label="ユーザーメニュー">
  <a role="menuitem" href="/profile">プロフィール</a>
  <a role="menuitem" href="/settings">設定</a>
  <div role="separator" aria-hidden="true"></div>
  <button role="menuitem">ログアウト</button>
</div>

Touch / Pointer

  • メニュー項目のは最低44pxの高さを確保する
  • メニュー外タップでメニューを閉じる(touchstart または mousedown で実装)

Contrast / Readability

  • メニュー項目のホバー・フォーカス背景のコントラストを確保する
  • 破壊的アクションの赤色テキストと背景のコントラストは4.5:1以上

10. 実装メモ(Implementation Notes)

  • shadcn/ui の DropdownMenu@radix-ui/react-dropdown-menu ベースで、role="menu"・キーボードナビゲーション・フォーカス管理・aria-haspopup・Floating UI による位置自動調整がすべて実装済み
  • メニューの位置計算(画面端での自動反転)は Floating UI(@floating-ui/react)を使うのが最善。placement="bottom-start" で展開方向を指定し、画面端では自動で反転する
  • aria-disabled="true" + pointer-events: nonedisabled 属性と異なりフォーカス可能なため、スクリーンリーダーが無効状態を伝えやすい。スクリーンリーダーユーザーのために無効な理由をTooltipで示すことも検討する
  • 三点リーダーボタンの aria-label は「オプション」だけでなく「記事『Button』のオプション」のようにコンテキストを含めると、複数の三点リーダーが並ぶ画面で識別しやすい

11. 関連リンク


12. まとめ

Dropdown Menuの設計はフォーカス管理が最重要です。迷ったら 4. 設計判断の核 に戻り、「開いたら最初の項目にフォーカス」「Escで閉じてトリガーに戻す」「三点リーダーには aria-label」の3点を確認してください。shadcn/ui の DropdownMenu を使えばこれらは自動的に解決されます。Selectとの混同に注意——アクションのリストには role="menu"、フォームの値選択には role="listbox" を使い分けることが、意味論的に正しいUI設計の基本です。

更新のお知らせ

サイトに載せていない実例や、新しい記事のお知らせはこちらで出しています。

読んだ内容を、自分の画面に当てるとき

UIXHEROは、記事を書くほかに、画面の検品・判定、デザインシステムの構築、実装と改善の伴走を受けています。何を頼めばいいか決まっていない段階の相談も、同じ窓口で受けます。

UIXHEROに頼めることを見る

※ 記事の内容についての質問や、書いてほしいテーマの要望も同じ窓口で受けています

記事をシェア

メールでお知らせを受け取る

最終更新: 2026年8月28日

この記事を書いた人

Dengen Yosho(DGYS)

Dengen Yosho(DGYS)

UI/UXデザイナー兼デザインエンジニア デザイン歴25年以上 情報設計〜UIデザイン〜React/TypeScriptによる実装までを一気通貫で担当 大手企業のDXプロジェクトや決済アプリ領域で、デザインリードとして改善と構築を経験 現在はフリーランスとして、プロダクトのUI/UX改善とデザインシステム構築を支援 長年の実務の中で感じてきたのは、 「良いUI」はセンスではなく、再現可能な判断の積み重ねであるということ UIXHEROは、 心理学や行動科学の知見を、現場で使える設計言語に翻訳するための場所 関心領域は「ユーザーの行動が変わるUI」 人の認知・注意・意思決定の構造を理解し、 “なぜそのUIが機能するのか”を言語化することを目指している

あわせて読みたい

この記事に関連する記事をご紹介します

Bar Chart(棒グラフ)

カテゴリごとの量を棒の長さで比べるチャート。ゼロ基線の扱い、並び順、縦横の選び方、しきい値の見せ方という設計判断と、色だけに頼らないアクセシビリティ要件を解説する。

2026年8月27日
18

Donut Chart(ドーナツチャート)

中央をくり抜いた円で構成比を示すチャート。中央に置く値の選び方、円グラフとの使い分け、リングの太さ、凡例の作りという設計判断と、色だけに頼らないアクセシビリティ要件を解説する。

2026年8月27日
17

Gauge Chart(ゲージチャート)

1つの値を範囲の中に置いて示す半円のチャート。範囲の両端に意味があるかという条件、しきい値の帯の設計、色だけで良否を伝えない書き方という設計判断とアクセシビリティ要件を解説する。

2026年8月27日
16

もっと深く知りたいですか?

ここに掲載されていないトピックについても、リクエストがあれば解説記事を追加します。 わかりにくい点や、具体的な事例について知りたいことがあれば教えてください。

リクエストを送る