CSS

[CSS] z-index とスタックコンテキスト

More than 1 year has passed since last update.

z-index を使って要素の重なりを制御するとき、何も考えずに適当に z-index: 100; などと指定したりしていませんか? このあたりの仕組みをよく理解せずに z-index を濫用していると、いつか怪奇現象に見舞われてつらいことになるかもしれません。


怪奇現象の例

早速ですが、以下のコードを御覧ください。


html

<div class='boxes'>

<div class='box1'>
.box1 { z-index: 1 }
</div>
<div class='box2'>
.box2 { z-index: 2 }
<div class='box3'>
.box3 { z-index: 0 }
</div>
</div>
</div>


css

.boxes {

color: white;
position: relative;
}
.boxes div {
width: 10em;
height: 10em;
position: absolute;
}
.box1 {
background-color: red;
top: 0;
left: 0;
z-index: 1;
}
.box2 {
background-color: green;
top: 3em;
left: 3em;
z-index: 2;
}
.box3 {
background-color: blue;
top: 3em;
left: 3em;
z-index: 0;
}

これをブラウザで開くとどのように表示されるでしょうか?

z-index の値を見た感じでは、 box2 > box1 > box3 の順番で重なって表示されそうですね。

しかしこれは以下のように表示されます。

z-index が一番小さいはずの box3 が最前面に表示されています。これは何故でしょうか。


スタックコンテキスト

CSS にはスタックコンテキスト(スタック文脈)という概念があります。

スタックコンテキストは、ある特定の要素をベースとした子孫要素の集合です。

html 要素は初期状態でルートスタックコンテキストを生成しているため、すべての要素は何らかのスタックコンテキストに所属しています。

スタックコンテキストを生成しうる「ある特定の要素」は、いくつかあるのですがひとつだけ挙げると


  • positionstatic 以外」かつ「z-indexauto 以外」である要素

です。

要するに、「z-index を有効にした要素はスタックコンテキストを生成する」ということです。

上記の例で言うと、box1, box2, box3 はすべてスタックコンテキストを生成しています。


z-index とスタックコンテキスト

z-index の値はスタックレベルと言い、要素の重なる順番を表すプロパティですが、実はこれは所属するスタックコンテキスト内での順番を指定するものです。

class
z-index
スタックコンテキスト
重なり順のイメージ

.box1
1
html (root)
root > 1

.box2
2
html (root)
root > 2

.box3
0
.box2
root > 2 > 0

.box3 のスタックレベルは 0 ですが、 .box3.box2 のスタックコンテキストに所属しているため、.box2 のスタックコンテキストに所属している要素集合の中でのスタックレベルが 0 である、ということです。

そのため、最終的な重なり順は box3 > box2 > box1 となるわけです。


まとめ

z-index の値が同じでもスタックコンテキストによって重なり順序が変わることがあるので、スタックコンテキストを意識してスタイルを書いていけると良さげ ₍₍⁽⁽(ી( ・◡・ )ʃ)₎₎⁾⁾


参考