Closed5

z-index の設計思想を言語化する

hirohiro

z-indexのルール

  • 極力、z-indexを使用しない
  • z-index0から4までの値を使用する
  • 原則として-1などの負数は使用しない

Layer Stackのルール

  • コンポーネントが持つべきz-indexの値を役割ごとにレイヤー(階層)上に定義する
  • 階層が重なるにつれてz-indexの値を増やしていく

Layer Stack 4 : z-index: 4

いかなる状態でも上に配置される要素。

  • モーダル
  • ドロワー
  • オーバーレイ

Layer Stack 3 : z-index: 3

常に上に配置されるような要素。

  • グローバルヘッダー(例: 追随する固定ヘッダー)

Layer Stack 2 : z-index: 2

  • ツールチップ
  • ポップオーバー
  • フローティングボタン(例: カルーセルなどの矢印ボタン)

Layer Stack 1 : z-index: 1

スタックを持たない要素の上に配置される。

  • バッジ

z-index の定義

:root {
  --layer-stack-1: 1;
  --layer-stack-2: 2;
  --layer-stack-3: 3;
  --layer-stack-4: 4;
}

.modal {
  z-index: var(--layer-stack-4);
}

.modal-in-modal {
  z-index: calc(var(--layer-stack-4) + 1);
}
hirohiro

isolationのルール

Layer Stack の定義だけだとコンポーネント同士でz-indexが競合し、意図しない重なりになってしまうケースも考えられる。その場合、isolationを利用してコンポーネントのルートにスタッキングコンテキストを生成させることで問題を解決することができる。

.special-components {
  isolation: isolate;  /* スタッキングコンテキストを生成させる */
  position: absolute;
}

.special-components__item {
  position: absolute;
  z-index: 100;
}

.modal {
  position: absolute;
  z-index: var(--layer-stack-4);
}

基本的にz-indexの指定だけで問題がない状態でのHTML構造が好ましいが、z-index: calc(var(--layer-stack-2) + 1); のような指定をした場合に他のコンポーネントとの重なりが意図しない状態になる可能性が高い。子要素にz-indexの指定があるコンポーネントのルートにはisolationの指定をしておくのが好ましい。

ちなみに、isolation登場以前はスタッキングコンテキストの生成のためにtransformを副作用のない指定をして生成するハックが存在していた(例:transform: scale(1))。


hirohiro

まとめ

  • z-indexLayer Stackのルールに従って指定する
  • コンポーネントのルートにはisolation: isolateを指定する
このスクラップは2022/05/18にクローズされました