Slide 1

Slide 1 text

2025 年の z-index‌ 設計を考える‌

Slide 2

Slide 2 text

[TL;DR] z-index の設計には色々なパターンがある z-index は CSS を(悪い意味で)簡単に終わらせる z-index に数値を直接指定するのは危険

Slide 3

Slide 3 text

z-index とは 01 z-index の設計を考える 02 03 まとめ [ 目次 ]

Slide 4

Slide 4 text

01 z-index とは

Slide 5

Slide 5 text

[概要] z-index は要素の重なりを制御するプロパティ z-index プロパティは整数値(正の数、ゼロ、負の数)で指定することができる position が static(初期値)以外の場合、または flex, grid アイテムの場合に機能する z-index に何も指定しない(auto)の場合、または同じ正の数、ゼロの場合は、 HTML 順に後ろに配置された要素が上に重なる z-index が負の数の同じ要素は前に配置された要素が上に重なる

Slide 6

Slide 6 text

戦闘力の数値が大きいやつがバトルで勝つ [z-index は戦闘力]

Slide 7

Slide 7 text

親要素にスタッキングコンテキストが生成されるとそのスコープ内での戦闘力となる 例えば「人間」というコンテキスト内では人間同士でバトルが始まる [スタッキングコンテキスト]

Slide 8

Slide 8 text

スタッキングコンテキスト内での戦闘力はあくまでコンテキスト内での戦闘力 グローバルに目を向けると人間界の中では最強でも戦闘力が平凡な熊にはバトルに勝てない [スタッキングコンテキスト]

Slide 9

Slide 9 text

スタッキングコンテキストは生成せずに常にグローバルで戦いたい… が、残念ながらスタッキングコンテキストは簡単に生まれてしまう position の値が absolute あるいは relative で、かつ z-index の値が auto 以外 position の値が fixed あるいは sticky display: flex あるいは display: grid の子要素で、かつ z-index の値が auto 以外 opacity の値が 1 未満 mix-blend-mode の値が normal 以外 transform、filter、perspective、clip-path、mask の値が none 以外

Slide 10

Slide 10 text

「ホバー時に透過しようとしたら z-index がバグります! どうしたらいいですか?」 opacity の値が 1 未満の時は スタッキングコンテキストが生成されるから

Slide 11

Slide 11 text

基本的にはスタックコンテキストの生成ありきで z-index は管理したほうがいい

Slide 12

Slide 12 text

02 z-index の 設計を考える

Slide 13

Slide 13 text

[破綻する理由] z-index がマジックナンバーと化している プロジェクトで使われている z-index の値を把握できていない 雰囲気で z-index を指定している(このくらいの数値にしておけば大丈夫だろ→もっと 前に出なきゃいけない何かが現れる→このくらいの数値にしておけば大丈夫だろの悪循 環) 他のコンポーネントの子要素の z-index とコンフリクトする 何でもかんでも z-index を指定して、どう重なるのか影響度合いがわかりにくい z-index: 999999(終わりの始まり💀)   など

Slide 14

Slide 14 text

[考え方] z-index を「絶対的」なものか「相対的」なものか考える 絶対的なもの → 固定配置の重ね順 (追従ヘッダーやその他 fixed や sticky な要素) 相対的なもの → コンポーネントルートを基準とした重ね順 (Block を基準とした Element の重ね順)

Slide 15

Slide 15 text

絶対的な z-index の設計

Slide 16

Slide 16 text

絶対的な z-index は グローバル変数で管理 する setting/stack.css を作成して、そこで 管理する 10の倍数などでで管理する マジックナンバーの回避 stack.css を z-index 管理表として扱う ポイント

Slide 17

Slide 17 text

絶対に表面に出す必要がある要素には z-index:calc(infinity) を指定する サードパーティ製の CSS の z-index よりも前に出す必要があるモーダルやローディングなどには z-index:calc(infinity) を指定して保険をかける

Slide 18

Slide 18 text

Tailwind でも同様 tailwind.config.js を拡張し、z-index 用 の設定を追加する Tailwind 標準のユーティリティはマジッ クナンバーと化すので使用しない ポイント

Slide 19

Slide 19 text

相対的な z-index の設計

Slide 20

Slide 20 text

原則的に z-index は使わずに DOM の順 番で制御する 指定する必要がある場合は 1(前面) か -1(背面) のみ使用する -1 はほぼ背景用 ポイント 相対的な z-index は なるべく使わないように 頑張る

Slide 21

Slide 21 text

スタックコンテキストの生成ありきで z-index は管理する Elementがコンポーネントの外側に出 ないようにして、他のコンポーネント の z-index との衝動を防ぐ ポイント コンポーネントには isolation:isolate を指定して スタッキングコンテキストを生成しておく isolation プロパティはスタッキングコンテキストの生成するか?を定義するプロパティ 他の手段より副作用が少ないのでスタッキングコンテキストを能動的に生成する場合は isolation: isolate を使用する

Slide 22

Slide 22 text

「コンポーネントに margin を持たせ るな」という原則と同様に、 「コンポーネントに相対的な z-index は持たせるな」 コンポーネント間の重ね順はコンポー ネントをレイアウトする親コンポーネ ントで制御する ポイント コンポーネントそのものに相対的な z-index は持たせない

Slide 23

Slide 23 text

「絶対的な z-index は 10 の倍数でグローバル変数で管理する」 「相対的な z-index は 1(前面) か -1(背面) のみ使用する」 でも、絶対誰かが z-index: 2 とかやりだすよね…😅 👆️

Slide 24

Slide 24 text

【提案】 相対的な z-index も変数管理して 数値指定を禁止にしよう

Slide 25

Slide 25 text

[相対的なz-indexも変数で指定する] stack.css に相対的定義を追加

Slide 26

Slide 26 text

[Stylelint で数値の指定を縛る]

Slide 27

Slide 27 text

[Tailwindの場合]

Slide 28

Slide 28 text

03 まとめ

Slide 29

Slide 29 text

z-index はスタックコンテキストありきで管理する z-index は絶対的 or 相対的なもので ジャンル分けして考える コンポーネントに 相対的な z-index を持たせない 治安悪化防止のために z-index の数値指定をやめよう (変数しか許容しないようにしよう)