UIXHERO

Popover(ポップオーバー)

トリガー要素をクリックすると展開するフローティングパネルUIコンポーネント。TooltipとModalの間を埋める存在として、インタラクティブなコンテンツ(フォーム・リンク・設定)を小さなパネルで提供する設計を解説する。

2026年3月3日
更新: 2026年9月14日
約22分
by Dengen Yosho(DGYS)

トリガー要素(ボタン・アイコンなど)をクリックすると展開するフローティングパネルコンポーネント。TooltipとModal Dialogの間を埋める存在で、インタラクティブなコンテンツ(リンク・フォーム・設定・フィルター)を小さなパネルで提供することが目的。モーダルと異なり背後のコンテンツを操作できる状態で共存する。

この記事を読むと、Tooltip・Modal・Dropdown Menuとの使い分け・フォーカス管理(開いたらパネル内の最初の要素にフォーカス)・Escape での閉じ方・ARIA dialog パターンとの使い分けが自分でできるようになります。


1. UI例(Preview / Live)

実装で見る(GunjoUI)

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

2. 定義(Definition)

トリガー要素をクリックすると展開するフローティングパネルUIコンポーネント。インタラクティブなコンテンツ(リンク・フォーム・設定)を含められる点でTooltipと異なり、背後のコンテンツを操作できる状態で共存できる点でModal Dialogと異なる。軽量な設定パネル・フィルター・カラーピッカー・ヘルプパネルに適する。

TooltipとPopoverの違い:Tooltipはホバー/フォーカスで表示される受動的な補足(テキストのみ・インタラクション不可)。Popoverはクリックで開く能動的なパネル(リンク・フォームを含む・インタラクション可)。

ModalとPopoverの違い:Modalは背後を操作できなくなる付きのオーバーレイ。Popoverは背後を操作できる状態で表示されるパネル。フォーカストラップの有無が主な違い。複雑な操作・重要な確認にはModalを使う。


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

3.1 When to use

  • 軽量な設定パネル(通知設定・表示設定など3〜5項目程度)
  • フィルター/ソートパネル(チェックボックス複数・スライダー)
  • カラーピッカー・日付ピッカーなどウィジェット型UI
  • ヘルプ / 情報パネル(リンク付きの補足説明)
  • インラインでの簡易編集(テキスト・タグの編集)

3.2 When NOT to use

  • 複雑なフォーム(10項目以上・確認が必要な操作)→ Modal Dialogを使う
  • 重要な確認・警告(削除確認など)→ Alert Dialogを使う
  • テキストのみの短い補足 → Tooltipを使う
  • コンテンツが多い(スクロールが必要なほど)→ Sheet / Drawerを使う

3.3 代替UI(Alternatives)

  • テキストの補足 → Tooltip
  • ユーザー情報のプレビュー → Hover Card
  • 複雑な操作・確認 → Modal Dialog / Alert Dialog
  • 多くのコンテンツ → Sheet / Drawer

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

Popoverの核は「Modal未満・Tooltip超え」の適切なサイズ感——背後を操作できる軽量さを保ちながら、インタラクティブなコンテンツを提供する。複雑になりすぎたらModalに昇格させる判断が重要。

判断の優先順位:① 複雑さの判断(Popover vs Modal)→ ② フォーカス管理 → ③ Escape で閉じる → ④ 外クリックで閉じる

  • 3〜5項目の設定・フィルターならPopover、それ以上ならModal:Popoverの中身が複雑になるほど、「この操作は重要なのにモーダルでなく軽く扱われている」というユーザーの不安が増す。操作の重要度・項目数でModalへの昇格を判断する
  • 開いたら最初のインタラクティブ要素にフォーカスを移す:Popoverが開いたら autoFocus またはuseEffectで最初の入力要素・ボタンにフォーカスする。フォーカスが移らないとキーボードユーザーがPopover内を操作できない
  • Escapeで閉じてトリガーにフォーカスを戻す:EscapeキーでPopoverを閉じた後、開いたトリガーボタンにフォーカスを戻す。これがないと次のTabキー操作で意図しない場所にジャンプする
  • 外クリックで閉じる:Popover外の要素をクリックした時にPopoverを閉じる。ただしトリガーボタン自体のクリックは開閉のトグルとして機能させる

5. 状態設計(States)

5.1 必須状態(Required)

  • Closed(閉じた状態):トリガーボタンのみ表示
  • Open(展開中):パネルが表示され、最初のインタラクティブ要素にフォーカス

5.2 条件付き状態(Conditional)

  • Loading:パネルのコンテンツがサーバーから取得中
  • Error:コンテンツ取得失敗
状態必須何を伝えるか
Closed✅展開可能(aria-haspopup で伝える)
Open✅パネルのコンテンツ

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

コンテンツの種類によって使い分ける。

バリアントコンテンツ使用例
設定パネルチェックボックス + ボタン通知設定・表示オプション
フィルターパネルチェックボックス複数 + リセット一覧画面のフィルター
ウィジェットカラーピッカー・日付ピッカーカラー選択・日付入力
情報パネルテキスト + リンクヘルプ・ツールの説明

禁止パターン:Popoverにフォーカストラップを実装する → フォーカストラップを付けるとModalと同等の重さになる。フォーカストラップが必要なほど重要な操作なら最初からModalを使う。


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

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

  • Popoverが開いてもフォーカスが移らない:キーボードユーザーがPopoverの存在に気づかず、Tabキーで次の要素に進んでしまう
  • Escapeで閉じた後フォーカスが行方不明:Popoverを閉じた後フォーカスが失われ、次のTabキーでページの先頭から操作し直しになる
  • Popoverの複雑化:Popoverの中にネストしたPopover・複雑なフォーム・長いコンテンツを詰め込み、Modal相当の重さになる

7.1 Bad(典型3つ)

  • <div onClick={open}>設定</div> でPopoverを開くが、キーボードで操作できない(<button> ではない)
  • Popoverが開いた後、フォーカスがトリガーボタンに残ったままで、Tabキーを押さないとPopover内の操作ができない
  • Popoverの中に10項目以上のフォームと「キャンセル」「確認」ダイアログを含め、実質的にModalと同等の操作になっている

7.2 Good(対になる3つ)

  • <button aria-haspopup="dialog" aria-expanded={isOpen}>設定</button> でトリガーを実装し、キーボードでも開閉できる
  • Popoverが開いたら useEffect で panelRef.current?.querySelector('button, input, a')?.focus() を呼び、最初のインタラクティブ要素にフォーカスを移す
  • 項目が増えてきたらPopoverをModalに昇格させ、フォーカストラップ・スクリーンリーダー向けの aria-modal="true" を追加する

7.3 How to fix(手順)

  1. トリガーに <button aria-haspopup="dialog" aria-expanded={isOpen}> を使う
  2. Popoverが開いた時の useEffect で最初の button, input, a, [tabindex] にフォーカスを移す
  3. onKeyDown に Escape を実装し、Popoverを閉じた後 triggerRef.current?.focus() でトリガーにフォーカスを戻す
  4. mousedown イベントで Popover外クリックを検知し、閉じる処理を実装する

8. ルール(Must / Better)

Must(守らないと壊れる)

Better(品質が跳ねる)


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

Keyboard

  • Enter / Space でトリガーボタンを操作してPopoverを開く
  • Tab / Shift+Tab でPopover内のフォーカス可能要素を移動
  • Escape でPopoverを閉じてトリガーにフォーカスを戻す

Focus

  • Popoverが開いたら最初のインタラクティブ要素にフォーカスを移す
  • 閉じた後はトリガーボタンにフォーカスを戻す
  • フォーカストラップは不要(Popover外をTabで抜けられる)

Screen Reader

<button
  aria-haspopup="dialog"
  aria-expanded="true"
  aria-controls="popover-settings"
>
  詳細設定
</button>

<div
  id="popover-settings"
  role="dialog"
  aria-label="通知設定"
>
  <!-- コンテンツ -->
</div>

Touch / Pointer

  • は最低44px
  • Popover内のコントロール(チェックボックス・ボタン)も44pxのタップ領域を確保する

10. 実装メモ(Implementation Notes)

  • shadcn/ui の Popover は @radix-ui/react-popover ベースで、aria-haspopup・フォーカス管理・Escape処理・外クリックで閉じる・Floating UIの位置計算がすべて実装済み
  • 位置計算(画面端での自動反転)は Floating UI の useFloating + autoPlacement または flip ミドルウェアで実装する。@radix-ui/react-popover では内部で自動処理される
  • は data-state="open" / data-state="closed" 属性と CSS s を組み合わせると Radix UI のPopoverでスムーズに実装できる

11. 関連リンク


12. まとめ

Popoverの設計は「Modal未満・Tooltip超え」のサイズ感の見極めが核心です。迷ったら 4. 設計判断の核 に戻り、「3〜5項目程度か(それ以上はModal)」「開いたら最初の要素にフォーカスが移るか」「Escapeでトリガーにフォーカスが戻るか」の3点を確認してください。shadcn/ui の Popover を使えばこれらの実装は自動的に解決されます。Tooltipとの最大の違いは「クリックで開く・インタラクティブ要素を含める」ことであり、この2点を満たす軽量なパネルが必要な時がPopoverの出番です。

更新のお知らせ

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

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

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

UIXHEROに頼めることを見る

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

記事をシェア

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

最終更新: 2026年9月14日

この記事を書いた人

Dengen Yosho(DGYS)

Dengen Yosho(DGYS)

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

あわせて読みたい

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

Day Band(いちにちの帯)

1日を1本の帯にして、時間帯を面で、節目を印で、いまの時刻とつまみを重ねて見せるUIコンポーネント。器が1日に固定されることの意味、4つの層の重ね方、印のラベルと時刻の数字を分ける理由、触った瞬間に動かさない理由を解説する。

2026年9月14日
約24分

Live Badge(LIVEの札)

隣の数字がいまの値かどうかを示す小さな札。状態を表す語を枠で囲って独立させる理由、明滅と色を補助に留める理由、実時間から外れたときに「古い」ではなく「いつの値か」を出す設計判断とARIA実装を解説する。

2026年9月14日
約21分

Time Transport(時間の操作盤)

いま映している時刻を、名前をつけた速さの段で動かし、決まった幅で飛ばし、ひと押しで「いま」へ戻すための操作盤。速さを連続値にしない理由、向きをアイコンに持たせる理由、状態を大きい表示の色で示さない理由を解説する。

2026年9月14日
約25分

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

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

リクエストを送る