19
JANUARY
ウェブFRIDAY 2024 / 1 / 19
popover属性を使ってみようと思ったけど時期尚早な模様
Text by Hiroyuki Matsumoto
popover属性で簡単にモーダルウィンドウが作れるような環境ができてきたのでその辺りの情報をまとめています。
※この記事は 2024.1.17 時点の情報を基に作成しています。
1. popover属性の対応状況
大半のブラウザでpopover属性がサポートされ、モーダルウィンドウがJavaScript無しで実装できるようになりました。
しかし まだサポートされていないブラウザがあります。Firefoxです。
※about:configの設定で dom.element.popover.enabled を true にすれば動きますがデフォルト設定では無効。
Firefoxは現在Nightly Buildとなっているバージョン124以降で正式サポートされる予定ですが、
iOSのバージョン16系(ひとつ前のメジャーバージョン)を使用しているユーザーなど、古い環境では動作しない場合があります。
caniuse.com によると77.99%のユーザーがpopover属性対応のブラウザを使っているとのことです。ということは残り22.01%では非対応となります。無視するには大き過ぎる数値なので非対応環境ではpolyfillを導入したいところです。
2. polyfillの導入
幸いPolyfillが公開されています。https://github.com/oddbird/popover-polyfill
こちらにある通りHTMLに
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%0Asrc%3D%22https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2F%40oddbird%2Fpopover-polyfill%40latest%22%0Acrossorigin%3D%22anonymous%22%0Adefer%0A%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
と加えれば一応導入できます。ただ、後述しますが色々と注意点がありますので、導入すればOKというものではありません。
2-1. popover属性をサポートしないブラウザでのみ読み込む
もうちょっとスマートにpopover属性をサポートしないブラウザの場合のみ読み込むようにする場合は下記のコードを適当なjavascriptファイルに入れましょう。
if(! HTMLElement.prototype.hasOwnProperty("popover")){ const elm = document.createElement('script'); elm.setAttribute('crossorigin', 'anonymous'); elm.defer = true; elm.src = 'https://cdn.jsdelivr.net/npm/@oddbird/popover-polyfill@latest'; document.head.appendChild(elm); }
3. polyfillの注意点
現時点では結構問題があります。大きな問題もあるため、JavaScriptで動作するタイプのモーダル系ライブラリを使ったほうがトラブルは少なそうです。。。
3-1. 擬似クラス(:popover-open) が使えない(代替策あり)
polyfillでは擬似クラスまでサポートを追加できません。代替手段としてモーダルウィンドウがオープンしている場合 :popover-open クラスが付与されますのでこれを適切に使いましょう。
なおCSSを記述する際、クラス名に :(半角コロン)を使う際は \ によるエスケープが必要です。
// モーダルウィンドウが .modal の場合の記述例 .modal.\:popover-open{ ... }
3-2. セレクタに ,(半角カンマ)を使うな → :isを使え
モーダルウィンドウが開いている際のCSSを記述する際、ネイティブ対応のブラウザとポリフィルで対応するブラウザの両方に対応したい場合、下記のように書きたくなると思います。
.modal:popover-open, .modal.\:popover-open{ ... }
ところがこの書き方だと、popover属性をサポートしないブラウザではこのスタイル指定は完全に無視されます。
非対応ブラウザからすると :popover-open という無効なセレクタが含まれているため、このブロック全体が破棄されるとのことです。※順序を逆にしても挙動は変わりません。
代わりに :is を使ったところFirefox/Safari16で正常に動作することを確認しました。
.modal:is(:popover-open, .\:popover-open){ ... }
3-3. popover属性に対応しないSafari(Ver.17未満)では常時モーダルウィンドウが表示されてしまう
// Polyfillが挿入するCSSの一部 :where([popover]:not(.\:popover-open)){ display:none; }
アクティブでないモーダルウィンドウを隠すためにpolyfillが上記のスタイルを挿入するのですが、これがSafariでは正しく解釈されません。
どうも :not疑似要素内でエスケープを使ったセレクタの指定ができないようです。これは対処が難しいですね…
3-4. polyfillではz-indexで位置を決めるだけなので、最前面にならないことがある
そのため非対応環境実機での動作検証が必要です。
なおpopover非対応ブラウザであっても、FirefoxとSafariでは少し挙動が異なるようです。
TEXT by
松本 博之(まつもとひろゆき)
1978年、鳥取県米子市生まれ。
株式会社マジックワード WEBシステムの開発・運用を担当。
WordPressの実績多数。表面的な使用方法を把握するだけでなく、WordPressのソースコードを読み解いて対応できます。
国家資格の応用情報処理技術者をなんとなくとりました。