Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
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