🛸

dialog タグを利用して、マルチプラットフォーム対応で、良い感じなモーダルUIを作る

2022/12/03に公開
1

Zennのみなさん、こんにちは!
株式会社TSUKURUBAで、Web フロントエンドエンジニアをしているkiiです
新卒で入社してもう1年半ほど経ちました。時間の進みを感じます🍂

はじめに

2022年3月、Safari(15.4)にも待望の<dialog>タグがやってきて、
モダンブラウザでは、Web標準の技術を用いて、簡単に良いモーダルUIを作れるようになる!と期待が高まったんじゃないでしょうか?

ただ現実的には、プロダクトやサイトの対応ブラウザバージョンを考慮すると、利用を躊躇してしまい、頑張ってJavaScriptを書いたり、既存のモーダルライブラリを利用して対応することも多いはず...😢

私も2022年5月に、Web Appのモーダルを新しく作ることになったのですが、
複数の実装方法で比較検討してみた所、
<dialog>タグを利用して、マルチプラットフォーム対応で良い感じのモーダルUIが作れそうだと分かりました💡
実際にプロダクト開発に利用した所上手くいったので、その知見を共有したいと思います📝

🚩 記事の目的

<dialog>タグを利用した良い感じのモーダルUIが作れる🧩

良い感じのモーダルUI

  • マルチプラットフォーム対応📱🖥
  • モーダルを操作している時に、背景がスクロールしない🖱
  • 各インターフェースで操作しやすい⌨️

スコープ外のこと

  • モーダルUI実装の方法比較検討
    • 対応ブラウザや既存システムの性質によりけりなので、今回は省きます
    • Scrapboxに軽く書いているので参考までにどうぞ。この記事の反応良ければ頑張ってまとめるかも...
  • dialogタグの細かい利用方法

🏃‍♂️ 3行まとめ

  • マルチプラットフォーム用に、dialog-polyfillを利用🤝
  • 後ろがスクロールしないようにするために、body-scroll-lockを利用🖱👆🏽
  • Code Exampleを用意したので、forkして遊んでみてください⚽️

📄今回、作りたいモーダルUIの要件定義

はじめに、今回作りたいモーダルUIの要件を整理します。

マルチプラットフォーム対応📱🖥

自身が提供するサービスの対応ブラウザ全てで、機能的、視覚的に問題なく利用出来る。
自身が提供するサービスの対応ブラウザは、各社それぞれ基準があると思います。
2022年現在だと、dialog要素に対応していないブラウザ(Safari iOS ver15.3以前など)を使っているユーザーが一定数いるので、dialog要素単体で実装することは難しそうです😢

Image from Gyazo

参考: https://caniuse.com/dialog

モーダルを操作している時に、背景がスクロールしない🖱👆🏽

Image from Gyazo

Dialog外の背景部分もスクロールで動いてしまっているgif

現在のdialogタグを利用しただけだと、dialog内でスクロールした際、dialog外もスクロールされてしまいます。

これだと、画面全体を覆うUIを作った際、謎に画面がスクロールされている現象に直面します。困りますね😥

各インターフェースで操作しやすい⌨️🖱📱

キーボード⌨️、マウス🖱、タッチ📱で操作出来る。
WebAppを利用しているユーザーは、様々な環境下で利用しています。それぞれのユーザーに正しく体験を提供したい所です。

特に、キーボード⌨️時のフォーカスがモーダルUI実装時に見逃されがちな割に、体験を悪化させるので、以下の点に注意したいです。

  • モーダルを開いた際、フォーカスをモーダルに「閉じ込め」て、Tab移動がモーダル内だけで行われる
  • モーダルを閉じたら、フォーカスがモーダルを開くボタンにフォーカスが移動する

🪄実現のための工夫

マルチプラットフォーム対応にするため、Polyfillを利用🎁

https://github.com/GoogleChrome/dialog-polyfill

dialog要素に対応していないブラウザ(Safari iOS ver15.3以前など)に対応するために、polyfillで挟んでサポートします。

幸い、Chromeチーム製のdialog-polyfillがあるので、そちらを利用します。最終リリース日が、2021年1月であることが気になりますが、自分が気になる各ブラウザで動作確認した所、特に問題なかったので利用しました。

モーダルUIの裏側をスクロールしないようにするために、body-scroll-lockを利用🖱

https://github.com/willmcpo/body-scroll-lock

dialogタグやdialog-polyfillでは、裏側のスクロール周りの扱いについてサポートされていないため、別途対応が必要です。

スクラッチでサポートするか何かしらのライブラリを利用する必要があります。
そんな時に、body-scroll-lockを利用します。

依存パッケージ無しで、2021年6月更新ですが一定利用されており、自身でスクラッチで記述するよりメンテが楽そうです。
もし、パッケージを利用したくない場合は、大したcode量じゃないので、body-scroll-lockのコードをコピペして調整するのもいいかもしれません。

キーボード操作のための、フォーカスの位置調整⌨️

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog

https://github.com/GoogleChrome/dialog-polyfill

こちらの要件は、新しい<dialog>の利用とdialog-polyfillで、ある程度カバー出来ました。(なんて便利なんでしょう✨)

⚽️Code Example

https://stackblitz.com/edit/multi-dialog-sample?file=scripts/dialog.js

今回の説明したものを含めたシンプルな例を作りました。参考にしたり、forkして遊んでみてください🙏
案外、実装が簡単なことが分かると思います!

また、記事化出来なかった注意点も、codeのコメントで残しています。特にiOS限定のバグ対処やその他体験改善の工夫を盛り込んでいます📝
(時間あれば、もっと見た目綺麗にして、記事に説明増やしたかった...🥺)
気になる所あれば、コメント下さい〜

おわりに

今回の実装方法だと、

  • モーダルUIライブラリのお作法を気にせずWeb標準のAPI使って、カスタマイズしやすい点
  • ユーザーの利用ブラウザのバージョンが上がったり、dialogタグの機能が拡張されると、ライブラリを剥がしてScriptのSizeを軽く出来る点、

が良いなと思っています!
今回の紹介で、dialog要素を利用して、簡単に良い感じのモーダルUIが作れたら、嬉しいです。

おわり

参考リンク群と補足

Building a dialog component

  • Adam Argyleさんが書いた神記事
  • dialogタグを利用して、凄く良い体験のモーダルUI作って紹介してくれています
  • 概念ごとに紹介してくれていて、とても分かりやすいです✨まず、見て各概念理解するのオススメします!

モーダルUIの調査メモ by kii

  • 一度、↑で紹介していますが、私がモーダルUI実装するにあたり、メモしていたノートです
  • 他の実装方法とか気になればどうぞ

実際作ったcowcamoのモーダルUI by kii

  • 実際に、私が作ったUIもこっそり共有しておきます。今後も更新すると思うので、真のExampleですね
  • 正直にいうと、直したい箇所たくさんあります...
  • 何か意見あれば、こっそり教えて下さい🙏お手柔らかに🥺
  • 東京付近住んでいるなら、cowcamoをぜひ、利用してみてくださいね🏡(宣伝)
GitHubで編集を提案

Discussion

kiikii

Note

2024/01/28 現在だと以下の構成がいいと思います。

対応ブラウザ基準

  • iOS16以上

実現方法

  • Dialog Polyfillを利用せず、Dialogタグを直接利用
  • スクロールロックは、overscroll-behaviorで実現