Popover APIを使ってJavaScriptなしでツールチップやドロップダウンメニューを実装する
Popover APIは、ツールチップやドロップダウンメニューをJavaScriptなしで実装できるAPIで、Baseline 2025に追加されました。表示するコンテンツにpopover属性を渡し、その要素をpopovertargetで制御します。シンプルなHTMLとCSSで手軽に機能に富んだポップオーバーを作成する方法を学びます。
はじめに
Popover APIがついにBaseline 2025に追加されました。 Popover APIはツールチップやドロップダウンメニューのようなUIを作成するためのAPIです。
ツールチップとドロップダウンメニュー
Tooltip
Dropdown Menu
このUIの実装はPopover APIを使っていません。
Popover APIはこれらのUIが持つ、表示レイヤーの管理やアクセシビリティを考慮した表示を行ってくれます。 これらの機能は、既存の機能では実装のハードルが高くライブラリを頼らざるを得ないことが多かったのでBaselineに追加されたことは大きな進歩です。
この記事ではPopover APIの基本的な使い方を紹介します。
Popover APIの全体像
Popover APIによって作られたポップオーバーは
- その外側をクリックすると閉じられる
- ESCキーを押すと閉じられる
- 開いた時にフォーカスが内部に移動する
- Top layer(重ね合わせコンテキストの最上位のレイヤー)に配置される
の性質を持ちます。
Popover APIは関連する3つのHTMLの属性と2つのCSSの機能が用意されています(それらを管理するJavaScriptの機能も存在しますが、この記事ではHMTLとCSSにだけ注目します)。
HTMLの属性はpopoverとpopovertarget、popovertargetaction、CSSの機能は::backdropと:popover-openです。
HTML属性
popover属性はポップオーバーで表示させたいコンテンツを指定します。
<p id="popover1" popover>ポップオーバーで表示されるコンテンツ</p>
デフォルトの値はautoです(JSXで記述する際は明示的に付与する必要がありそうです)。値をmanualにするとESCキーの押下や外側のクリックで閉じられなくなります。manualは主にJavaScriptを使って制御する場合に使用します。
ポップオーバーの表示を管理する要素にはpopovertarget属性を付与します。管理するコンテンツを伝えるために、値にはpopoverを持たせた要素のidを渡します。
<button popovertarget="popover1">
ポップオーバーの表示を管理する要素
</button>
popovertargetactionはpopovertarget属性が付与された要素が、ポップオーバーで表示させる要素の管理方法を指定します。
<button popovertarget="popover1" popovertargetaction="show">
クリックでポップオーバーを表示
</button>
デフォルトは表示非表示を切り替えるtoggleです。その他にも表示だけさせるshowと、非表示にするだけのhideがあります。
CSS機能
ポップオーバー要素の後ろには全画面を覆うコンテンツが配置されます。::backdropはそんな背景にスタイルを付与するための擬似要素です。
::backdrop {
background-color: #00000080;
}
::backdropはPopover API専用の擬似要素ではなく、dialog要素のようなTop Layerに配置される要素の背景にスタイルを渡す時に利用されます。
:popover-openはポップオーバーが表示されたときにスタイルを付与する擬似クラスです。
.popover:popover-open {
min-width: 50vw;
}
サンプル
Popover APIを使った簡単な例を紹介します。3つのボタンがあり、それぞれ異なるpopovertargetactionを持っています。
表示されるコンテンツは:popover-openを利用して、開閉時のアニメーションを付与しています。
Popover APIのサンプル
このポップオーバーはPopover APIによって表示されました。 ESCキーやこのコンテンツの外側のクリック、toggleまたはhideボタンで閉じられます。
<div class="wrapper">
<button popovertarget="popover1" popovertargetaction="toggle">
popovertargetaction: toggle
</button>
<button popovertarget="popover1" popovertargetaction="show">
popovertargetaction: show
</button>
<button popovertarget="popover1" popovertargetaction="hide">
popovertargetaction: hide
</button>
</div>
<p id="popover1" popover>
このポップオーバーはPopover APIによって表示されました。
ESCキーやこのコンテンツの外側のクリック、toggleまたはhideボタンで閉じられます。
</p>
.wrapper {
display: flex;
flex-wrap: wrap;
gap: 2rem;
}
#popover1 {
border-radius: 0.5rem;
margin: auto;
padding: 1rem;
max-width: calc(1 / 3 * 100%);
opacity: 0;
transition: opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}
#popover1:popover-open {
opacity: 1;
}
@starting-style {
#popover1:popover-open {
opacity: 0;
}
}
::backdrop {
background-color: #00000080;
}
おわりに
この記事ではPopover APIの基本的な使い方を紹介しました。
Popover APIは表示するポップオーバーをpopover属性で表し、その表示を管理する要素にpopovertarget属性を渡すことで利用できます。
従来はJavaScriptで実装する必要があったツールチップやドロップダウンメニューの表示非表示を、HTMLとCSSだけで簡単に実装できるようになったのは大きな進歩でした。
サンプルで画面の中央にポップオーバーを表示していたように、まだ表示位置を制御する方法は提供されていません。
CSS Anchor Positioningが利用可能になると、HTMLとCSSだけでポップオーバーやツールチップの位置を制御できるようになるので、表示を誘発する要素の側にポップオーバーを表示することが可能になります。
Popover APIの登場がとてもありがたいと同時に、CSS Anchor Positioningへの期待も高まりますね。