
こんにちは!静岡県浜松市でWEBデザイナーをしています小瀧です。
Web制作の現場で、一見単純そうに見えて深みにハマるCSSの罠といえば…
そう、z-indexが効かない問題です。
- 「数値を上げても重ならない」
- 「position指定しているのに奥に隠れてしまう」
- 「親要素の影響? それともブラウザバグ?」
私も駆け出しの頃、深夜にこの謎に悩まされ、数時間かけてコードを一行ずつコメントアウトする羽目になったことがありました。。。
この記事では、現場で即試せる3ステップの対処法をまとめます。
CSSのスタッキングコンテキストの基礎から、意外と知られていないtransformやopacityが作る新しいコンテキストの落とし穴まで、「効かない原因」を順番に洗い出しながら解決する方法をお伝えします。
z-indexが効かないときの3ステップ対処法
ステップ1:positionとスタッキングコンテキストを確認
z-indexが効かない原因の多くは、position指定の有無です。
z-indexは、position: relative / absolute / fixed / sticky が指定されている要素にしか効きません。
さらに、親要素がtransformやfilterを指定していると、その要素自体が新しいスタッキングコンテキストを作り、子要素のz-indexが外の要素に影響しなくなるケースがあります。
.parent {
position: relative; /* これが必要 */
transform: translateY(0); /* これで別コンテキスト発生 */
}
.child {
position: absolute;
z-index: 9999;
}
ステップ2:親要素同士のz-index競合を疑う
次に確認したいのが、親要素の重なり順です。
子要素にいくら大きいz-indexを指定しても、親要素のスタック順序を超えることはできません。
- 兄弟要素のz-index設定を比較する
- 親要素がposition指定されているか確認する
- 必要なら親要素側のz-indexも調整する
ステップ3:不要なCSSプロパティを削除して切り分け
それでも解決しない場合は、一時的にCSSを最小限にして原因を特定します。
特に下記プロパティは新しいコンテキストを作りやすいため注意。
- transform
- filter
- opacity(値が1未満の場合)
- mix-blend-mode
具体例:重ならないバナーを修正するケース
例えば、固定ヘッダー上にポップアップバナーを重ねたいのに、なぜかバナーがヘッダーの下に潜り込むことがあります。
原因はヘッダーにposition: relative; z-index:10;が指定されており、バナーの親要素がスタッキングコンテキスト外だったためです。
修正例
.header {
position: relative;
z-index: 10;
}
.banner {
position: fixed;
top: 0;
z-index: 100;
}
z-indexトラブルを避けるための予防策
- z-indexの値をむやみに大きくしない(100や9999ではなく段階管理)
- レイヤー設計を最初に決めておく(ヘッダー・モーダル・通知バーなど)
- スタッキングコンテキストを作るプロパティを理解しておく
まとめ
- position指定とスタッキングコンテキストを確認する
- 親要素のz-index競合を調べる
- transformやopacityなど不要なプロパティを外して検証する













