ポップオーバーはウェブのあらゆる場所で使用されています。メニュー、トグルチップ、ダイアログで確認できます。アカウント設定、開示ウィジェット、商品カードのプレビューなどの機能に使用されています。これらのコンポーネントは普及していますが、ブラウザで構築するのは依然として非常に面倒です。この問題を解決するため、ポップオーバーを構築するための新しい 宣言型 HTML API がブラウザに導入されます。その最初の API が Popover API です。
ポップオーバーはダイアログと混同されることがよくありますが、動作にはいくつかの重要な違いがあります。dialog 要素は、dialog.showModal
(モーダル ダイアログ)で開いた場合、モーダルを閉じるために明示的なユーザー操作が必要なエクスペリエンスです。popover はライトディスミスをサポートしています。モーダル dialog はサポートしていません。
モーダル ダイアログでは、ページの残りの部分が操作できなくなります。popover は操作できます。違いについて詳しくは、こちらをご覧ください。
この記事は、e コマース企業が新しい CSS と UI 機能を使用してウェブサイトを強化した方法について説明するシリーズの一部です。この記事では、Tokopedia が Popover API を実装してどのようにメリットを得たかについて説明します。
Tokopedia
ポップオーバー属性を使用することで、React のコード行数を最大 70% 削減できました。モーダルは、JavaScript でイベント処理を行う必要がなく、
React.createPortalを使用してモーダル DOM をdocument.bodyの末尾に移動する代わりに、HTML でネイティブに制御できます。また、@starting-styleを使用して、ポップオーバーの 開閉をアニメーション化することもできます。—Tokopedia、シニア ソフトウェア エンジニア Andy Wihalim 氏
Tokopedia の商品詳細ページ(PDP)には、各商品の複数の商品画像が表示されます。商品のサムネイルをクリックすると、モーダルが開き、拡大画像が表示されます。これは、e コマース ウェブサイトでよく使用されるパターンです。
コード
Tokopedia は、フロントエンド開発に React を使用しています。このモーダルに Popover API を実装する前は、DOM モーダルとボタンを使用していました。ボタンを押すと、React の状態が変わり、モーダルが開きます。Popover API では、ポップオーバーを開く要素に popovertarget 属性を指定し、ポップオーバー要素の ID と同じ値を設定します。
この基本的な実装では、ポップオーバーは機能しますが、アニメーションなしで表示と非表示が切り替わります。ポップオーバーのスムーズな表示と非表示のアニメーションを作成するには、:popover-open と @starting-style を使用して、個別のプロパティのアニメーションを許可します。
次のコード例では、
transform: 'scale()' プロパティを使用して、ポップオーバーの拡大と縮小を行っています。
このコード例は、Popover API の表示と非表示のアニメーションを実装する方法を 示しています。
<Thumbnail popovertarget="medialightbox" />
<MediaLightbox popover id="medialightbox" />
export const cssModalWrapper = css({
background: NN0,
border: 'none',
borderRadius: '.625rem',
width: 1024,
padding: 24,
'&::backdrop': {
opacity: 0,
transitionProperty: 'opacity, display',
transition: '.25s ease-out',
transitionBehavior: 'allow-discrete',
},
transitionProperty: 'transform, opacity, display',
transition: '.25s ease-out',
transitionBehavior: 'allow-discrete',
transform: 'scale(0.8)',
opacity: 0,
'@starting-style': {
transform: 'scale(1)',
opacity: 1,
},
'&:popover-open': {
transform: 'scale(1)',
opacity: 1,
'@starting-style': {
transform: 'scale(0.8)',
opacity: 0,
},
},
});
Popover API をサポートしていないブラウザに対応するため、Tokopedia は popover-polyfill を oddbird によって実装しました。これは、gzip 圧縮でわずか 3.2 KB です。このポリフィルは問題なく動作し、パフォーマンスの低下もなかったため、満足しています。全体として、Popover API を使用することで、React のコード行数を最大 70% 削減できました。
Popover API を使用する際の考慮事項
Tokopedia は React を使用しています。このチームは、ポップオーバー コンポーネントを使用しないページのポップオーバー コンポーネントをアンマウントし、ポップオーバー コンテンツのコード分割を行うことで、コード分割を実現しました。これにより、初期リクエストのサイズを削減できました。
ポップオーバーを他の要素に対して配置するには、ポップオーバーと CSS アンカー ポジショニング (Chrome に近日登場) を組み合わせることを検討してください。これは、メニューやツールチップなどに便利です。
リソース
- Introducing the popover API
- The difference between a popover and a dialog
- バグを報告したい場合や、新機能をリクエストしたい場合は、ぜひお知らせください。
このシリーズの他の記事では、e コマース企業がスクロール駆動型アニメーション、ポップオーバー、コンテナクエリ、has() セレクタなどの新しい CSS と UI 機能を使用してどのようにメリットを得たかについて説明しています。