CSSのプロパティz-index
は要素の重なり順を制御するために使われますが、「z-indexが効かない!」という状況に遭遇したことはありませんか?その原因の多くはスタックコンテキストです。
この記事では『z-index』と『スタックコンテキスト』について、以下の内容を図とサンプルコードを用いてわかりやすく解説します。
z-index
が効かない例- スタックコンテキストとは
z-index
とスタックコンテキストの関係
z-indexが効かない例
z-index
を設定しているのに期待通りに動作しない場合があります。以下のサンプルコードと実行結果を見てみましょう。
<div class="container">
<div class="rect div-1">.div-1 ( z-index: 1 )</div>
<div class="rect div-2">
.div-2 ( z-index: 2 )
<div class="rect div-2-1">.div-2-1 ( z-index: 21 )</div>
<div class="rect div-2-2">.div-2-2 ( z-index: 22 )</div>
</div>
<div class="rect div-3">.div-3 ( z-index: 3 )</div>
</div>
.container {
color: white;
position: relative;
}
.rect {
width: 250px;
height: 100px;
position: absolute;
}
.div-1 {
background-color: red;
top: 0;
left: 0;
z-index: 1;
}
.div-2 {
background-color: green;
top: 50px;
z-index: 2;
}
.div-2-1 {
background-color: blue;
top: 20px;
left: 200px;
z-index: 21;
text-align: right;
}
.div-2-2 {
background-color: orange;
top: 70px;
left: 200px;
z-index: 22;
text-align: right;
}
.div-3 {
background-color: purple;
top: 100px;
z-index: 3;
}
これをブラウザで開くと以下のように表示されます。
z-index
の値の大きさは.div-1
→.div-2
→.div-3
→.div-2-1
→.div-2-2
ですが、.div-3
が最前面に表示されています。これはスタックコンテキストが原因です。
スタックコンテキストとは
CSSには「スタックコンテキスト(重ね合わせコンテキスト)」という概念があります。
スタックコンテキストは、CSSで要素の重ね順(z-index
)を制御する際の独立した空間のようなものです。z-index
を設定して要素の重なり順をコントロールする場合、スタックコンテキスト内でしか効果を発揮しません。
スタックコンテキストを生成するための条件はいくつかあります。例えば、以下の要素はスタックコンテキストを生成します。
position
の値がabsolute
またはrelative
であり、かつz-index
の値がauto
以外の要素- 例:
position: relative; z-index: 1;
- 例:
position
の値がfixed
またはsticky
の要素- 例:
position: fixed;
- 例:
例えば、ある要素の「position
の値がabsolute
またはrelative
であり、かつz-index
の値がauto
以外」の場合、この要素はスタックコンテキストを生成し、その中に含まれる子要素は、このスタックコンテキスト内でのみz-index
を影響を受けます。
冒頭に示したサンプルコードにおいて、.div-2
は新しいスタックコンテキストを生成しています。そのため、.div-2-1
や.div-2-2
は、.div-2
内でのみz-index
の値が有効です。一方、.div-3
は、.div-2
の外側にあるルートスタックコンテキストに所属しているため、.div-2-1
や.div-2-2
よりも上に表示されます。
html
要素はデフォルトでルートスタックコンテキストを生成しているため、すべての要素は何らかのスタックコンテキストに所属しています。
MDN
スタックコンテキストに関しては以下のMDNのページに詳しく記載されています。
補足
- スタックコンテキストは「スタッキングコンテキスト」や「重ね合わせコンテキスト」や「スタック文脈」とも言います。
.div-1
,.div-2
,.div-2-1
,.div-2-2
,.div-3
はすべて新しいスタックコンテキストを生成しています。
z-indexとスタックコンテキストの関係
z-index
は要素の重なり順を制御するプロパティですが、その要素が所属するスタックコンテキストの中でのみ有効です。冒頭に示したサンプルコードを表に示すと以下のようになります。
クラス名 | z-index | 所属するスタックコンテキスト | 重なり順のイメージ |
.div-1 | 1 | html (ルートスタックコンテキスト) | root > 1 |
.div-2 | 2 | html (ルートスタックコンテキスト) | root > 2 |
.div-2-1 | 21 | .div-2 (新しいスタックコンテキスト) | root > 2 > 21 |
.div-2-2 | 22 | .div-2 (新しいスタックコンテキスト) | root > 2 > 22 |
.div-3 | 3 | html (ルートスタックコンテキスト) | root > 3 |
.div-2-1
や .div-2-2
の z-index
がどれだけ大きくても、 .div-3
の上に重なることはありません。これは.div-2-1
と.div-2-2
が .div-2
のスタックコンテキスト内に限定されているからです。そのため、最終的な重なり順は.div-1
→.div-2
→.div-3
→.div-2-1
→.div-2-2
となります。
本記事のまとめ
この記事では『z-index』と『スタックコンテキスト』について、以下の内容を説明しました。
z-index
が効かない原因z-index
は所属するスタックコンテキスト内でのみ効果を発揮するから
- スタックコンテキストを生成する条件(一例)
position: relative/absolute
かつz-index
がauto
以外。position: fixed/sticky
。
- スタックコンテキストの仕組み
- スタックコンテキスト内の
z-index
は、その中でのみ評価され、外部には影響しない。
- スタックコンテキスト内の
お読み頂きありがとうございました。