CSS transformがスタッキングコンテキストを作成する仕組み

CSS transformを要素に追加すると新しいスタッキングコンテキストが作成され、z-indexの動作が予期せず変化する理由を理解します。

Stacking Contexts

詳細な説明

transformスタッキングコンテキストの罠

最も一般的なz-indexの驚きの1つは、要素にtransformプロパティを追加すると、突然子要素のz-indexの動作が変わることです。これはnone以外のtransform値が新しいスタッキングコンテキストを作成するために発生します。

問題

/* 変更前:固定ヘッダーが正常に動作 */
.page { position: relative; }
.header { position: fixed; z-index: 100; top: 0; }

/* 変更後:.pageにtransformを追加するとfixed配置が壊れる */
.page {
  position: relative;
  transform: translateX(0); /* スタッキングコンテキストを作成! */
}
.header {
  position: fixed; /* ビューポートではなく.pageに対してfixedになる */
  z-index: 100; /* .pageのコンテキスト内でのみ比較される */
}

これをトリガーするプロパティ

transform: translateZ(0);       /* GPUアクセラレーションハック */
transform: translate3d(0,0,0);  /* 別のGPUハック */
transform: scale(1);            /* 一見何もしない */
transform: rotate(0deg);        /* これも一見何もしない */
will-change: transform;         /* 意図を宣言するだけでも */

よくあるシナリオ

  1. GPUアクセラレーションハック:アニメーションパフォーマンスを向上させるためにtransform: translateZ(0)will-change: transformを追加すると、固定配置の子要素やz-indexの順序が壊れる可能性があります。

  2. CSSアニメーション:transformプロパティを使用するCSSキーフレームアニメーションのある要素は、アニメーション中にスタッキングコンテキストを作成します。

  3. ホバー効果:親のホバートランスフォームが子要素のスタッキング順序を予期せず変更する可能性があります。

解決策

/* 親のtransformの代わりにisolationを使用 */
.page {
  isolation: isolate; /* transformの副作用なしにコンテキストを作成 */
}

/* またはfixed要素を含まないラッパーにtransformを移動 */
.page-inner {
  transform: translateX(0);
}

検出

z-indexシステムで、transformfilteropacity < 1、またはwill-changeを使用するレイヤーをスタッキングコンテキストを作成するものとしてマークします。このツールの「ctx」トグルでこれらの相互作用を追跡できます。

ユースケース

親要素にCSS transformやアニメーションを追加した後、固定配置のヘッダーやサイドバーが突然固定されなくなった場合、スタッキングコンテキストの作成を理解することでDOMやCSSの再構築に役立ちます。

試してみる — z-index Manager

フルツールを開く