Slide 1

Slide 1 text

Popoverを早速実践投入してついでに ブラウザにバグ報告もした話 2025.03.12 | kaonavi Tech Talk #20〜 フロントエンドスペシャル vol.3 〜 © kaonavi, inc.

Slide 2

Slide 2 text

uhyo 株式会社カオナビ フロントエンドエキスパート 業務ではフロントエンドの開発効率の向上に尽力。 好きなHTML要素はtime要素。 発表者紹介 © kaonavi, inc. 2

Slide 3

Slide 3 text

これまでのあらすじ © kaonavi, inc. 3

Slide 4

Slide 4 text

z-indexの管理がつらい どこのご家庭にもあるグローバルな z-indexカタログ!! 場当たり的なz-indexの修正!!! © kaonavi, inc. 4

Slide 5

Slide 5 text

汎用コンポーネントに z-indexの指定機能が増える 使う場所によって適切なz-indexが異なるので、 さまざまなコンポーネントにz-indexが生えてとてもつらい © kaonavi, inc. 5

Slide 6

Slide 6 text

z-indexの理想と現実 理想的には、重ね合わせコンテキスト を活用し、 グローバルなz-indexの管理はせず、0と1のみといったローカルな管理をすべき。 ポップアップなど浮いてる系のコンポーネントに職人芸で z-indexを指定して回る のはバグの元になり、開発効率も低下する。 なるべく職人芸が必要ないように軌道修正をしたいが、 すでに大量のz-indexが使われているプロダクトを壊さずに修正するのは たいへん難しい。 © kaonavi, inc. 6

Slide 7

Slide 7 text

救世主としての popover Popoverとは、HTMLの比較的新しい機能で、要素をトップレイヤーに表示できる という特徴がある。 トップレイヤーに表示された要素は、 それ以外の要素よりも上に表示される 。 (z-indexを53万とかにしてもトップレイヤーには勝てない) © kaonavi, inc. 7

Slide 8

Slide 8 text

Popoverの基本 メニューを開く

メニュー

閉じる
© kaonavi, inc. 8 popover属性を指定することでその要素は popoverになる。 JavaScriptを使わずに開閉したり、 popoverの外をクリックしたら閉じるといった 挙動も標準でサポート。

Slide 9

Slide 9 text

ReactとPopover React(宣言的UI)を使っている場合、HTMLだけでpopoverの挙動を記述できる 機能をフル活用するのは難しい。 完全にJavaScriptから挙動を制御できるpopover="manual"があるので今回はこちらを使 用。 (一応、非制御コンポーネント的な感じにすれば HTMLの機能を活用する方針も行けなくはな さそうだが……) 今回の目的としては、とにかくトップレイヤーを活用できれば十分。 © kaonavi, inc. 9

Slide 10

Slide 10 text

Popoverの活用法 特に浮いてる系の汎用コンポーネントは、 popoverに寄せていきたい。 これ系の要素は、基本的に一番上に来ればいいので、 ややこしいz-index管理をしなくても自動的に一番上に来る ようにすれば大抵は問題ない。 © kaonavi, inc. 10

Slide 11

Slide 11 text

Popoverコンポーネント爆誕 ということで、Reactから使いやすい形でまとめたコンポーネントを 用意した。 使い勝手としてはFloating UIのFloatingPortalみたいな感じ。 浮いてるコンテンツ © kaonavi, inc. 11

Slide 12

Slide 12 text

とはいえ © kaonavi, inc. 12

Slide 13

Slide 13 text

Popoverの重なり順も管理できると嬉しい とはいえ、popover同士(トップレイヤー同士)の重なり順も、 全く制御しないわけにはいかない。 例えば、ページのコンテンツから発生した Popoverよりも、 モーダルダイアログのほうが上に来てほしい。 Popoverコンポーネントには、重なり順を制御するための priority propを追加した。 © kaonavi, inc. 13

Slide 14

Slide 14 text

Popoverは“やり直し”の手段である priority propがz-indexの二の舞になっては困るので、 意味を持ったenum的な管理にした。 言い換えれば、popoverは重なり順の管理に関してやり直しの機会を与えてくれた。 © kaonavi, inc. 14

Slide 15

Slide 15 text

sugaoでのPopover利用 カオナビのデザインシステム・コンポーネントライブラリである sugaoで Popoverコンポーネントを導入開始。                         これとか → © kaonavi, inc. 15

Slide 16

Slide 16 text

Popover普及策 従来z-indexを使って実装されていたものをいきなり Popoverに変えたら プロダクトが壊れる恐れがあるので、 既存のコンポーネント にはPopoverをオプトインで実装。 プロダクト側で、画面単位でPopover利用するかどうかを切り替えられる。 新規コンポーネントでは Popoverのみサポートすることにより、 Popoverへのオプトインを促す。(今ここ) © kaonavi, inc. 16

Slide 17

Slide 17 text

Popoverの重なり順の制御 © kaonavi, inc. 17

Slide 18

Slide 18 text

重なり順を直接操作する方法は存在しない 現在のところ、Popover(というかトップレイヤー)の重なり順を直接制御する 方法は存在しない。以下のルールだけが存在する。 ● トップレイヤーでは、後からトップレイヤーに追加された要素が上に表示される そのため、「既存のPopoverよりも下に表示されてほしい新しい Popover」みたいな ものを画面に追加するためには 工夫が必要。 © kaonavi, inc. 18 これが後から増えたときとか

Slide 19

Slide 19 text

重なり順を制御する工夫 Popoverは開いた順に重なるので、 Popoverが新たに表示されるときは全部のPopoverを望ましい順番に閉じて開き直す ことで 意図通りの重なり順にできる。 強引だがこれしか方法がない。 (実際にはこれだとPopover内にあったフォーカスが消えちゃうなど問題もあるので、開き直す 操作は最小限にしている) © kaonavi, inc. 19

Slide 20

Slide 20 text

ということで実装してみたが …… バックドロップ付きのPopoverの重なり順制御で問題が発生。 Google Chromeとそれ以外(Firefox, Safari)で挙動が違う…… Dialog(バックドロップ付きでトップレイヤーに表示される)を 閉じてすぐ開き直した場合、バックドロップの位置がおかしい。  当時のFirefoxの表示(正しい)    当時の Chromeの表示(おかしい) © kaonavi, inc. 20

Slide 21

Slide 21 text

Google Chromeのバグ Dialogを閉じてすぐ開き直した場合、 仕様に従ってDialogはトップレイヤーの一番上に再配置されるが、 ChromeではDialogのバックドロップが付いてこない という問題があった。       初期状態                  正しい表示      当時の Chromeの表示               Dialogを一瞬閉じて              すぐ開き直す © kaonavi, inc. 21 Dialogのバック ドロップ Popover Dialogのバック ドロップ Dialog Dialog Popover Dialogのバック ドロップ Popover Dialog

Slide 22

Slide 22 text

Google Chromeのバグ Google Chrome(正確にはChromium)にバグ報告したら10日くらいで修正された。 https://issues.chromium.org/issues/360158414 無茶な使い方したせいでChromeのバグ修正にも貢献できた! (少なくとも当時は)誰もやっていない Popoverの使い方をしたということで、 フロンティアを走ってる感があり個人的には満足。 (ただ無茶な使い方なのは確かなので重なり順を変える APIが欲しい気もする) © kaonavi, inc. 22

Slide 23

Slide 23 text

まとめ © kaonavi, inc. 23

Slide 24

Slide 24 text

まとめ PopoverというHTMLの機能を、グローバルなz-indexの管理がつらいという問題に 対処するために導入した。 トップレイヤーに表示されるという特徴を生かして、混沌に満ちた既存の重なり設計を やり直す機会として活用した。 このように新しい機能はブラウザ実装も完璧ではなく、バグがあることもある。 そういうのを見つけてWebに貢献できるのは面白い。 © kaonavi, inc. 24