要素を重ね順で前面・背面に配置したいときによく使う z-index
。しかし、指定しても意図通りに反映されないことがあります。これは CSS の「スタッキングコンテキスト」の仕組みに起因するケースが多いです。この記事では、z-index が効かない原因を整理し、正しい解決方法を紹介します。
z-index の基本
z-index
は要素の「スタッキングコンテキスト」内での重なり順を決めるプロパティです。数値が大きいほど前面に表示されます。ただし、z-index が効くのは position
が relative
、absolute
、fixed
、sticky
の要素だけです。
.front {
position: relative;
z-index: 10;
}
.back {
position: relative;
z-index: 1;
}
原因1:position が指定されていない
デフォルトの static
のままでは z-index が効きません。必ず position を指定しましょう。
.box {
position: relative; /* static のままでは無効 */
z-index: 5;
}
原因2:親要素のスタッキングコンテキストに閉じ込められている
親要素が新しいスタッキングコンテキストを作ると、その外側の要素より前面に出すことができません。z-index の数値が大きくても、異なるコンテキスト間では比較されないため「効かない」ように見えます。
.parent {
position: relative;
z-index: 1; /* ← 親がコンテキストを作る */
}
.child {
position: absolute;
z-index: 9999; /* 親の外には出られない */
}
この場合、親要素の z-index を調整するか、不要な z-index を外してコンテキストを作らないようにしましょう。
原因3:transform や opacity が指定されている
transform
、opacity < 1
、filter
、perspective
などを指定すると、新しいスタッキングコンテキストが生成されます。これも子要素の z-index が効かなくなる典型例です。
.parent {
transform: translateZ(0); /* GPU アクセラレーション目的の指定でもコンテキスト発生 */
}
.child {
position: absolute;
z-index: 9999; /* それでも親の外には出られない */
}
解決には transform を外すか、外せない場合は親要素自身の z-index を適切に調整します。
原因4:Flexbox や Grid の仕様
Flexbox や Grid の子要素は、z-index
を指定しなくても描画順によって重なりが決まります。さらに z-index
を効かせるには position を明示する必要があります。
.flex-item {
position: relative; /* これがないと z-index が効かない */
z-index: 10;
}
原因5:負の z-index の扱い
z-index: -1
のように負の値を指定すると、親要素の背景より後ろに描画されます。そのため要素が「消えた」ように見えることがあります。意図的に背面へ送るなら問題ありませんが、表示されないときはこの仕様を確認してください。
よくある解決方法まとめ
- 必ず position を
relative
以上に指定する - 親要素が不要に z-index を持っていないか確認する
- transform や opacity が新しいコンテキストを作っていないか確認する
- Flex/Grid の子要素は position を付ける
- 負の z-index は表示順序に注意する
まとめ
z-index が効かないときは「スタッキングコンテキスト」の仕組みを理解すると原因が分かります。単純に数値を大きくするのではなく、親子関係や position、transform の有無を見直すことが正しい解決方法です。