これはすごい! HTMLの新機能、popover属性でポップオーバーがJavaScript無しで簡単に実装できるようになります
Post on:2023年6月8日
先日リリースされたChrome 114でPopover APIがサポートされ、HTMLのpopover
属性が使用できるようになりました。
今まではポップオーバーを実装するのにはJavaScriptを使用し、ポップオーバーの開閉・フォーカス・アクセスフックなど面倒でしたが、popover
属性で実装すると驚くほど簡単で、さまざまなUIコンポーネントに利用できます。
Introducing the popover API
by Una Kravets
下記は各ポイントを意訳したものです。
※元サイト様のライセンスに基づいて翻訳しています。基づいてというのは、貢献部分に関して同ライセンスも含みます。
- はじめに
- HTMLのpopover属性とは
- ポップオーバーのデフォルト、オーバーライド
- 自動ポップオーバーと手動ポップオーバー
- popover属性とdialog要素の違い
- 近日公開予定の便利な2つの機能
- 終わりに
はじめに
ポップオーバーは、Web上のあらゆる場所に存在します。それはメニュー、トグルチップ、ダイアログで見ることができ、アカウント設定、開示ウィジェット、プロダクトカードのプレビューで表示されることもあります。
これらのUIコンポーネントが普及しているにもかかわらず、ポップオーバーを実装するのは驚くほど手間がかかります。フォーカス、開閉状態の管理、コンポーネントへのアクセスフック、エクスペリエンスに出入りするためのキーボードバインディングを管理するためのスクリプトを実装する必要があります。ポップオーバーの便利な機能を実装する前に、これらすべての実装をする必要があります。
この面倒な問題を解決するために、Chromium 114のPopover APIから始まるポップオーバーを構築するための新しい宣言型HTML APIのセットがブラウザに提供されました。
参考: The Popover API. -New in Chrome 114
HTMLのpopover属性とは
popover
属性を使用すると、これまでの複雑な実装を自分で管理するのではなく、ブラウザにpopover
属性と一連の機能ですべてをブラウザの処理に任せることができます。HTMLのポップオーバーは以下をサポートしています。
-
- 最上位のレイヤーに昇格
- ポップオーバーはページの他の要素よりも上のレイヤーに表示されるため、
z-index
を管理する必要はありません。 - 最上位レイヤーについて詳しくは、下記をご覧ください。
CSSのz-index: 10000;はいらなくなる、要素を最上位に表示する「最上位レイヤー(top layer)」の基礎知識と使い方
-
- ライトディスミス機能
- ポップオーバーの領域外をクリックすると、ポップオーバーが閉じてフォーカスが戻ります。
-
- デフォルトのフォーカス管理
- ポップオーバーを開くと、ポップオーバー内で次のタブが停止します。
-
- アクセシブルなキーボードバインディング
- escキーを推すと、ポップオーバーを閉じてフォーカスが戻ります。
-
- アクセシブルなコンポーネントバインディング
- ポップオーバーの要素とトリガーを意味的に結びつけます。
JavaScriptを使用せずに、これらすべての機能を備えたポップオーバーを簡単に実装できるようになります。ポップオーバーの実装には、以下の3つが必要です。
- ポップオーバーを含む要素の
popover
属性(L.3) - ポップオーバーを含む要素の
id
(L.3) id
値と同じ値を持つポップオーバーを開く要素のpopovertarget
(L.1)
1 2 3 4 5 |
<button popovertarget="my-popover"> Open Popover </button> <div id="my-popover" popover> <p>I am a popover with more information.<p> </div> |
たったこれだけでのHTMLで基本的なポップオーバーを実装できます。実際の動作はデモページでご覧ください。
See the Pen
Simple default popover by web.dev (@web-dot-dev)
on CodePen.
このポップオーバーは追加情報を伝えるため、または開示ウィジェットとして使用できます。
HTMLのpopover
属性は2023年6月現在、Chrome 114, Edge 114でサポートされており、Safari 17でもサポート予定です。
Popover APIのサポートブラウザ -Can I Use
ポップオーバーのデフォルト、オーバーライド
前述のコードのように、デフォルトではpopovertarget
を使用して実装すると、ポップオーバーは開くボタンや要素で開閉が切り替わります。しかし、popovertargetaction
を使用して明示的なポップオーバーを実装することもできます。これはデフォルトのトグルアクションをオーバーライドします。
popovertargetaction
のオプションには、以下があります。
popovertargetaction="show"
: ポップオーバーを表示します。popovertargetaction="hide"
: ポップオーバーを非表示します。
popovertargetaction="hide"
を使用すると、次のコードのようにポップオーバー内に「閉じる」ボタンを実装できます。
1 2 3 4 |
<button popovertarget="my-popover" popovertargetaction="hide"> <span aria-hidden=”true”>❌</span> <span class="sr-only">Close</span> </button> |
実際の動作はデモページでご覧ください。
See the Pen
Simple default popover with close button by web.dev (@web-dot-dev)
on CodePen.
自動ポップオーバーと手動ポップオーバー
popover
属性を記述することは、実際にはpopover="auto"
と同じ意味になります。デフォルトのpopover
を開くと、祖先のポップオーバーを除き、他の自動ポップオーバーは強制的に閉じられます。ライトディスミスやクローズボタンで解除することができます。
そして、popover="manual"
を設定すると、別のタイプのポップオーバーつまり手動ポップオーバーが作成されます。このポップオーバーは他の要素タイプを強制的に閉じたり、ライトディスミスを介して閉じることはできません。タイマーまたは明示的な閉じるアクションを使用して閉じる必要があります。popover="manual"
に適したポップオーバーの種類は、通知などの表示されたり消えたりするがページの他の部分に影響をおよぼさない要素です。
実際の動作はデモページでご覧ください。
See the Pen
Basic manual popover with close button by web.dev (@web-dot-dev)
on CodePen.
上記のデモを操作してみると、ポップオーバーの領域外をクリックしても、ポップオーバーを非表示にできないことが分かります。また、他のポップオーバーが表示されていても閉じることはありません。
この違いを確認するには、
popover="auto"
は自動ポップオーバーで、
- 開いたら、他のポップオーバーを強制的に閉じます。
- ライトディスミス可能。
popover="manual"
は手動ポップオーバーで、
- 他のポップオーバーを閉じません。
- ライトディスミス不可能。トグルやクローズアクションで閉じてください。
ポップオーバーのスタイリング
ここまでHTMLで実装する基本的なポップオーバーについて学びました。しかし、popovet
には優れたスタイリング機能もあります。その一つが、::backdrop
をスタイルする機能です。
auto
のポップオーバーでは、::backdrop
は最上位レイヤーのすぐ下にあるレイヤーになり、ページの残りの要素よりも上に位置しています。ポップオーバーを半透明の上に表示したい場合は、次のように::backdrop
にスタイルするだけです。
1 2 3 |
#size-guide::backdrop { background: rgb(190 190 190 / 50%); } |
実際の動作はデモページでご覧ください。「Size Guide」をクリックすると、ポップオーバーが表示されます。
See the Pen
Popover demo: Sizing Guide by web.dev (@web-dot-dev)
on CodePen.
デフォルトでポップオーバーは2pxのボーダーがあり、UIの中央に配置されます。しかし、これはカスタマイズが可能です。popover
は他のHTML要素と同様にサイズ・背景・位置などを変更できます。
popover属性とdialog要素の違い
注意すべてことは、popover
属性はそれ自体でセマンティクスを提供しないことです。また、popover="auto"
を使用してモーダルダイアログのようなエクスペリエンスを実装できますが、この2つにはいくつかの重要な違いがあります。
dialog.showModal
で表示されたdialog
要素(モーダルダイアログ)は、モーダルを閉じるために明示的なユーザー操作を必要とするエクスペリエンスとなります。popover
はライトディスミスをサポートしていますが、dialog
で実装したモーダルはサポートしていません。dialog
はページの残りの部分を不活性にしますが、popover
はそうではありません。
dialog
要素について詳しくは、下記をご覧ください。
HTMLの<dialog>要素とCSSで、モーダル・ダイアログ ボックスを実装する方法と注意点
実際の動作はデモページでご覧ください。
See the Pen
Popover Demo: Product Cards by web.dev (@web-dot-dev)
on CodePen.
上記のデモは、ポップオーバーの挙動を持つセマンティックダイアログです。つまり、ページの残りの部分は不活性ではなく、ダイアログのポップオーバーはライトディスミスのビヘイビアを取得することを意味します。このポップオーバー動作を備えたダイアログは、次のコードで実装できます。
1 2 3 4 5 6 7 8 9 |
<button popovertarget="candle-01"> Quick Shop </button> <dialog popover id="candle-01"> <button class="close-btn" popovertarget="candle-01" popovertargetaction="hide">...</button> <div class="product-preview-container"> ... </div> </dialog> |
WhatWGとOpenUIでは現在、HTMLの人間工学に基づいたダイアログ要素を開く機能について議論しています。これはpopover
に似ていますが、ページの残りの部分を不活性にするなど前述したダイアログの機能を保持するものです。popover
, dialog
, selectmenu
のような新しい要素の将来についてはこれらのグループに注視してください。
近日公開予定の便利な2つの機能
インタラクティブな開閉
display: none;
のアニメーション化や最上位レイヤーからのアニメーション化など、個別のプロパティをアニメーション化する機能はまだブラウザで利用できません。しかし、これらの機能はChromiumの次期バージョンで計画されています。
CSSの個別のプロパティをアニメーション化させる機能と、:popover-open
と@starting-style
を使用することで、変更前と変更後のスタイルを設定して、ポップオーバーを開いたり閉じたりするときにスムースなトランジションを可能にすることができます。
下記のデモをご覧ください。前述と同じポップオーバーの開閉をしますが、こちらの開閉はよりスムーズになり、より滑らかなユーザーエクスペリエンスをサポートします。
See the Pen
Popover demo: Sizing Guide - Animated by web.dev (@web-dot-dev)
on CodePen.
この機能はまだ確定していませんが、デモページをご覧になるときはChrome Canaryで#experimental-web-platform-featuresのフラグをオンにしてください。
display: none;
のアニメーション化について詳しくは下記をご覧ください。
CSSのこの新機能、すごく楽しみ! UI要素にさまざまなアニメーションを簡単に実装できるようになります
アンカーの位置決め
ポップオーバーはビューポートに基づいてアラートやモーダルを使用したい場合に最適です。しかし、メニューやツールチップなど他の要素との相対的な位置関係が必要な場合にも役立ちます。ここでCSSによるアンカーの出番です。
下記のデモでは、ラジアル型のメニューがPopover APIとアンカーの位置決めを使用して、各アイテムがトリガーであるボタンに固定されていることが確認できます。
アンカーの設定はポップオーバーの設定と似ています。
1 2 3 4 5 6 7 |
<button id="menu-toggle" popovertarget="menu-items"> Open Menu </button> <ul id="menu-items" popover anchor="menu-toggle"> <li class="item">...</li> <li class="item">...</li> </ul> |
アンカーにid
(上記では#menu-toggle
)を設定して、anchor="menu-toggle"
で2つの要素をつなげます。これでanchor()
を使用してポップオーバーのスタイルを設定できるようになります。トグルのベースラインに固定された中央寄せのアイテムは次のように設定します。
1 2 3 4 5 |
#menu-items { bottom: calc(anchor(bottom)); left: anchor(center); translate: -50% 0; } |
実際の動作はデモページでご覧ください。
See the Pen
Radial Menu Popover by web.dev (@web-dot-dev)
on CodePen.
これでアイテムはトグルボタンに固定され、ポップオーバーの組み込み機能を備えた完全に機能するポップオーバーのメニューが完成しました。JavaScriptは必要ありません!
CSSによるアンカーにはさらにエキサイティングな新機能として、@try
文で利用可能なビューポートスペースに基づいてメニューの位置を入れ替えることもできます。詳しくは、Chrome Canaryで#experimental-web-platform-featuresフラグをオンにしてデモをご覧ください。
終わりに
Popover APIはWebアプリケーションの実装をより簡単に管理し、デフォルトでアクセシブルな一連の新機能の最初のステップです。このポップオーバーがどのように使用されるか、非常に楽しみにです!
以下は、追加の資料です。
sponsors