z-index: 1より弱いが手前に表示される要素について
実験
モーダルのような画面の手前に重なる要素を、position:absoluteで位置指定すると、要素が手前に重なっているように見える。
<div class="relative">
メインコンテンツ
<div class="absolute">モーダル</div>
</div>
.relative {
position: relative;
width: 200px;
height: 200px;
background-color: gray;
}
.absolute {
position: absolute;
width: 100px;
height: 100px;
background-color: skyblue;
top: 50px;
left: 50px;
}

モーダルはメインコンテンツの子要素だからメインコンテンツよりも手前に表示されるのは当たり前だ。では、モーダルのdivタグの後ろに次のようなhtmlを追加するとどうだろうか。
<div class="relative">
メインコンテンツ
<div class="absolute">モーダル</div>
<p class="icon">😊</p> //追加
</div>
.icon {
margin: 0;
font-size: 100px;
}

アイコンはモーダルよりも後に出現するhtmlにも関わらず、モーダルの方が手前に表示されている。
要素の重ね合わせには次のようなルールがある。
どの要素にも z-index プロパティが指定されていない場合、要素は以下の順序で(下から上に)重ね合わせられます。
ルート要素の背景と境界
位置指定なしの子孫ブロック、 HTML 内での出現順
位置指定ありの子孫要素、 HTML 内での出現順
つまり、モーダルはpositionプロパティを持っているおかげで、後に出現するアイコンよりも手前に表示されているということだ。
次に、iconにtransformプロパティを設定してみる。
.icon {
transform: translateX(50px); //追加
margin: 0;
font-size: 100px;
}

すると、アイコンがモーダルよりも手前に出てきた。transformプロパティは、重ね合わせコンテキストを生成するため、z-indexを指定しているのと同じように手前に表示される。
では、transformプロパティが作る重ね合わせコンテキストとz-index: 1が作る重ね合わせコンテキストはどちらがより手前に表示されるだろうか?
今度はモーダルにz-index: 1を指定する。
.absolute {
position: absolute;
width: 100px;
height: 100px;
background-color: skyblue;
top: 50px;
left: 50px;
z-index: 1; //追加
}

アイコンはモーダルに隠れてしまった。transformプロパティが作る重ね合わせコンテキストはz-index: 1よりも弱いということだろうか?さらに、アイコンのCSSにz-index: 2を指定してみた。
.icon {
transform: translateX(50px);
margin: 0;
font-size: 100px;
z-index: 2; //追加
}

兄弟要素でz-indexがより大きい値にも関わらず、アイコンはモーダルの後ろに隠れてしまった。ここで気づいたが、そもそもz-indexは位置指定要素と一緒に使わないと効果がないのだ。

まとめ
- positionプロパティはz-indexと併用しなくてもpositionプロパティなしの要素より手前に表示される
- transformプロパティはz-index: 1よりも弱い重ね合わせコンテキストを生成する
- z-indexは位置指定要素positionと併用することで重ね合わせコンテキストを生成する
- このようなことがあるので、重ね合わせを意図してpositionプロパティを指定した要素にはz-indexを忘れずに指定するべきだ
Discussion