- ブラウザの標準機能だけでページ上に表示されるポップオーバーUIを作成でき、メニュー・候補・通知のようなパターンをより一貫して実装できる
- Popover API のポップオーバーは常に非モーダルであるため、ページ操作をブロックする必要がある UI には `` のほうが適している
- 単純なトグルは
popover、popovertarget、popovertargetaction のようなHTML 属性で処理でき、必要に応じて JavaScript メソッドで表示状態を制御する
::backdrop、:popover-open、beforetoggle、toggle などでスタイルや状態変化を扱え、interest invokers は JavaScript なしで hover/focus 表示をサポートする
- 2025年1月から最新のデバイスとブラウザで動作するBaseline 2025機能だが、古い環境や一部の詳細機能の互換性は確認が必要
Popover APIが解決する問題
- Popover API は、他のページコンテンツの上にポップオーバーコンテンツを表示する標準的な仕組みを提供する
- ポップオーバーは HTML 属性だけで制御することもでき、JavaScript API で表示・非表示の状態を直接扱うこともできる
- Web 上で overlays、popups、popovers、dialogs などと呼ばれてきた UI パターンを、ブラウザ標準機能としてより一貫して実装できる
モーダルが必要なら `` を使う
- ポップオーバー UI は大きくモーダルと非モーダルに分かれる
- モーダルでは、ポップオーバー表示中はページの残り部分と対話できない
- 非モーダルでは、ポップオーバーが表示されていてもページの残り部分と引き続き対話できる
- Popover API で作成したポップオーバーは常に非モーダルである
- ページ操作をブロックするモーダルなポップオーバーが必要なら `` 要素が適している
のように に popover を適用する方法も有効で、ポップオーバー制御と dialog のセマンティクスを併用できる
基本的な使い方
- Popover API は、ユーザー操作が必要な UI によく使える
- アクションメニュー
- カスタム toast 通知
- フォーム要素の候補
- コンテンツ選択 UI
- 学習用 UI
- HTML だけで簡単なポップオーバーのトグルボタンを作成できる
Toggle the popover
Popover content
- JavaScript では
HTMLElement.togglePopover() でポップオーバーの表示/非表示状態を切り替える
- API は、ポップオーバーの状態変化に反応するイベントと、スタイリングを支援する CSS 機能もあわせて提供する
HTML 属性
interestfor
- HTML
、、要素や SVG 要素をinterest invokerとして定義する
- 値は対象要素の
id であり、invoker 要素で interest が表示または消失するときに対象要素が影響を受ける
popover
- 要素をポップオーバー要素に変えるグローバル属性
- 値として
"auto"、"hint"、"manual" の状態を取れる
popovertarget
または 要素をポップオーバー制御ボタンにする
- 値は制御対象のポップオーバー要素の ID
popovertargetaction
- 制御ボタンがポップオーバーに対して行う動作を指定する
- 指定可能な値は
"hide"、"show"、"toggle"
CSSで扱う表示状態
::backdrop
- ポップオーバー要素のすぐ後ろに置かれる全画面の疑似要素
- 必要に応じてポップオーバー背後のページコンテンツにぼかしなどの効果を与えられる
interest-delay、interest-delay-start、interest-delay-end
- ユーザーが interest を示した、または失った時点と、ブラウザが反応する時点の間に遅延時間を追加する
:interest-source、:interest-target
- interest が表示されている状態で、invoker と接続された対象要素にそれぞれスタイルを適用できる
:popover-open
- ポップオーバー要素が表示中のときだけマッチする疑似クラス
- 開いている状態のポップオーバーのスタイリングに使う
JavaScript インターフェースと DOM 拡張
InterestEvent
interest と loseinterest イベントのイベントオブジェクト
- 接続された interest invoker 要素への参照を含む
source 属性を持つ
ToggleEvent
- ポップオーバー要素が表示状態と非表示状態の間で切り替わるときに発生するイベントを表す
beforetoggle と toggle イベントのイベントオブジェクト
interestForElement
- interest invoker が対象とする要素への参照を取得または設定する
HTMLButtonElement、HTMLAnchorElement、HTMLAreaElement、SVGAElement で使用できる
HTMLElement.popover
- JavaScript で要素のポップオーバー状態を取得または設定する
"auto"、"hint"、"manual" の値を使い、機能検出にも利用できる
- HTML グローバル属性
popover の値を反映する
popoverTargetElement
HTMLButtonElement と HTMLInputElement で、制御ボタンが制御するポップオーバー要素を取得または設定する
- HTML
popovertarget 属性に対応する JavaScript 機能
popoverTargetAction
HTMLButtonElement と HTMLInputElement で実行するポップオーバー動作を取得または設定する
"hide"、"show"、"toggle" の値を使い、popovertargetaction 属性を反映する
メソッドとイベント
HTMLElement.hidePopover()
- ポップオーバー要素を top layer から除去し、
display: none を適用して非表示にする
HTMLElement.showPopover()
- ポップオーバー要素を top layer に追加して表示する
HTMLElement.togglePopover()
- ポップオーバー要素を表示状態と非表示状態の間で切り替える
beforetoggle
- ポップオーバー要素の状態が表示と非表示の間で切り替わる直前に発生する
- ポップオーバーを開くのを防いだり、ポップオーバー状態に応じて他の要素を更新したりするのに使える
toggle
- ポップオーバー要素の状態が切り替わった直後に発生する
interest
- interest invoker の対象要素で interest が表示されると発生する
loseinterest
- interest invoker の対象要素で interest が消えると発生する
例と仕様リンク
1件のコメント
Hacker News の意見
Popover API は、CSS アンカー位置指定(CSS Anchor Positioning) まで入ってくれば、本当に大きな変化をもたらしそう
アンカー位置指定は、ページ上の別の要素を基準に要素を配置できるようにするもの
Popover API と組み合わせれば、カスタムツールチップやコンテキストメニューを宣言的に実装でき、PopperJS のようなライブラリも不要になる
https://developer.chrome.com/blog/tether-elements-to-each-ot...
https://popper.js.org/docs/v2/
https://developer.chrome.com/blog/anchor-positioning-api
https://caniuse.com/css-anchor-positioning
先週、新しい Popover API で何か作ってデプロイしてみようとしたが、すべてのブラウザで位置指定のサポートが不足していて、ユースケースが大きく制限された
最後のブラウザである Firefox も、すでにベータ版でアンカー位置指定を入れているようなので、そう長くはかからなさそう
titleのようなツールチップ属性がないのは驚きモーダルダイアログが必要なら
<dialog>要素もあるhttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/di...
<details>を使える不思議なことに、
<dialog>や<details>と違って、<popover>は属性だけで宣言的にopen状態を作れないように見える欠けている機能のように感じるし、この判断に根拠があったことを願う
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/de...
十分可能ではあるが、決して些細な作業ではない
Safari のサポートまでは時間がかかったが、今ではどこでも使える
タグを自分で組み合わせるより良いと思う
ホスト OS のウィンドウシステムと連携して実装されるなら、この機能は確かに必要に見える
現在のポップオーバーは、常にうまく動くとは限らない方法で真似しなければならないため
たとえばブラウザネイティブの
<select>はブラウザウィンドウの境界を越えて展開できるので、ウィンドウに切られる心配をしなくてよいが、Quasar のようなツールキットの凝った偽 select はそれができず、配置の選択肢が制限されるきちんとやるなら、win32 では各ポップオーバーが独自のネイティブ
HWNDを持ち、Cocoa/macOS では独自のNSViewの中にある必要がありそう今のブラウザが実際にそう実装しているのか、それとも単にブラウザウィンドウ内に重ね描きしているだけなのか気になる
Web サイトが指定されたビューポートの外に描画できることを許可すると、
alert()、confirm()、[title]のようなごく限られた場合を除き、ブラウザや OS のダイアログをもっともらしく真似するのがずっと簡単になるたとえば、ページがパスワードマネージャ拡張機能のロック解除ウィジェットを真似できる
これは大きなセキュリティリスクであり、限定的な利点に比べて価値がないと思う
これは理論上の懸念ではない
詐欺師たちは何年も前から、ブラウザクロームまで含めた偽のポップアップウィンドウなど、非常にもっともらしい偽 UI を作ってきており、ドラッグすら可能だった
ビューポート境界の外に描画できないことは、彼らが回避できなかったほぼ唯一の制限だった
小さなデバイスでは Web ブラウザがほぼ常に全画面を覆い、大きなモニターでも通常は少なくとも一つの角に接している
アクセシビリティやクロール可能性の面でもそうだし、誰かが「ポップアップ禁止」プラグインを作りたい場合にも有用
この機能は、ブラウザのメインプロセスでレンダリングされる権限付きの [X]HTML でのみ使える XUL 要素を通じて公開されている
一般の Web ページに枠なしの OS ウィンドウを作る権限を与えたいブラウザ開発者はいないと思う
一部の標準コントロールがそのように動作するのは、OS ネイティブで実装されているために生じる OS ごとの実装上の副作用であり、必ずそう実装しなければならないわけでもない
ブラウザには組み込みのポップアップブロッカーがあるのに、こういう API を作るというのは少し笑える
違いがあるのは分かるけど、それでもそう思う
90年代後半から2000年代初頭のポップアップ/ポップアンダー戦争を覚えているくらいの年齢ではある
その戦いには勝ったようだが、私たちの注意をめぐる戦争はまだまだ先が長い
ポップオーバーは必要なときに文脈情報を見せる浮遊要素だ
言及しているものはまったく別物
ポップアップは OS にゴミのようなウィンドウをばらまき、最悪の場合はコンピュータの使用そのものを妨げる
ポップオーバーダイアログはタブを閉じれば終わり
このスタイルのポップオーバーは情報を見せるのにかなり有用で、すでにずいぶん前から使われてきた
うっとうしく使われることはあり得るが、モーダルと同じように本当に多くのユースケースがある
今でも既存の
divなどでポップオーバーは実装できる例: https://getbootstrap.com/docs/5.3/components/popovers/
変わるのは、魔法のような追加ライブラリなしでポップオーバーを実装できる点だ
明示的な “popover” 要素をブロックしたところで、人々はカスタムライブラリを使い続けるだけ
人々がポップアップを嫌うのは、侵入的で別ウィンドウを持つからだ
この API は
divモーダルを置き換え、開発者の時間とコードを減らしてくれるこの API はその境界を破らない
その境界が破られるとシステムの使いやすさと安全性が下がるので、望ましくない方向だ
「Popover API で作ったポップオーバーは常に非モーダルだ。モーダルなポップオーバーを作りたいなら
<dialog>要素が適切だ」とあるが、なぜそうなのか分からないこれはポップオーバーの正当なユースケースだ
特に開いたときに背景をぼかすならなおさらで、ぼかされたボタンをユーザーのクリックで誤って押せるようにできるなら、その機能をなぜ提供しているのか疑問だ
調べてみると、両者を組み合わせることはできる
「ポップオーバー制御とダイアログの意味論を組み合わせたいなら、
<dialog>要素をポップオーバーにできる」という感じだそれならここでは
modalのような属性のほうが筋が通るのではないかと思うユースケースを明確に認めているのだから
<dialog>のほうがずっと先に存在していたからだと思うとても良い
正しく理解しているなら、新機能を導入するというより、モーダル
div、マスクdiv、コンテナdiv、面倒な位置指定 CSS が必要だった部分を単純化するもののようだスタイリングを簡単にする擬似クラスも追加されていて、気に入った
隠しチェックボックスを無理やり使わなくてよくなる
スタイリングやアニメーション付きのポップオーバーまで JS なしでどこまでいけるかは分からないが、フォーカス処理がきちんと行われる JS なし対応は良い
アクセシビリティ対応も組み込みだと言いたいところだが、今の仕様では見つけられなかった
スクリーンリーダーのようなアクセシビリティツールに要素を知らせるところまで処理してくれるなら、大いに助けになる
手動でやると、かなり簡単に抜け落ちるからだ
間違いなく有用だ
デモ: https://mdn.github.io/dom-examples/popover-api
Chrome でも Firefox でも、サブメニューが消える前の遅延時間を実装した人が誰もいないからだ
数十年分のユーザー体験研究が消え去っており、ほぼ予想どおりだ
https://mdn.github.io/dom-examples/popover-api/nested-popove...
かっこよく見えるが、このページにはなぜポップオーバーが何かを示す画像が一つもないのか分からない
https://mdn.github.io/dom-examples/popover-api/
インタラクティブなサンプルにはリンクしているが、ポップオーバーの基本スタイルはそれほど面白く見えない
https://mdn.github.io/dom-examples/popover-api/
素晴らしい
Popper を使って Stimulus で作ったカスタム実装はここにある
https://github.com/tramlinehq/tramline/blob/main/app/javascr...
そしてダイアログ用の実装はここにある
https://github.com/tramlinehq/tramline/blob/main/app/javascr...