z-indexをつかって要素の順番を変えていたのですが、どうにも思った通りにいかないことがありました。
今回はそんなハマったパターンになります。
親子関係になっているタグで親要素に z-index: auto
以外の値を指定した場合
<html>
<head>
<title></title>
<style type="text/css">
.parent {
padding-top: 20px;
padding-left: 20px;
width: 100px;
height: 100px;
background-color: #ff0000;
position: relative;
z-index: 2;
}
.child {
width: 100px;
height: 100px;
background-color: #ff9999;
position: absolute;
top: 60px;
left: 60px;
z-index: 1;
}
</style>
</head>
<body>
<div class="parent">
z-index 2
<div class="child">z-index 1</div>
</div>
</body>
</html>
疑似要素を設定している状態で要素にz-index: auto
以外を指定した場合
<html>
<head>
<title></title>
<style type="text/css">
.parent {
padding-top: 20px;
padding-left: 20px;
width: 100px;
height: 100px;
background-color: #ff0000;
position: relative;
z-index: 2;
}
.parent:before {
content: "before z-index: -1";
width: 100px;
height: 100px;
background-color: #ff9999;
position: absolute;
top: 60px;
left: 60px;
z-index: -1;
border: 1px solid #333;
}
.parent:after {
content: "after z-index: -2";
width: 100px;
height: 100px;
background-color: #ffdddd;
position: absolute;
top: 10px;
left: 80px;
z-index: -2;
border: 1px solid #333;
}
}
</style>
</head>
<body>
<div class="parent">z-index 2</div>
</body>
</html>
親要素にopacityをつけた場合
<html>
<head>
<title></title>
<style type="text/css">
.parent {
width: 100px;
height: 100px;
background-color: #ff0000;
position: relative;
opacity: 0.5;
}
.child {
width: 100px;
height: 100px;
background-color: #ff9999;
position: absolute;
top: 50px;
left: 50px;
z-index: -1;
}
</style>
</head>
<body>
<div class="parent">
z-index 2
<div class="child">z-index -1</div>
</div>
</body>
</html>
親要素にtransform指定した場合
<html>
<head>
<title></title>
<style type="text/css">
.parent {
width: 100px;
height: 100px;
background-color: #ff0000;
position: relative;
transform: rotate(-10deg);
}
.child {
width: 100px;
height: 100px;
background-color: #ff9999;
position: absolute;
top: 50px;
left: 50px;
z-index: -1;
}
</style>
</head>
<body>
<div class="parent">
z-index auto
<div class="child">z-index -1</div>
</div>
</body>
</html>
親要素にposition: fixed、position: stickyを指定した場合
<html>
<head>
<title></title>
<style type="text/css">
.parent {
margin: 20px;
width: 100px;
height: 100px;
background-color: #ff0000;
position: fixed;
}
.child {
width: 100px;
height: 100px;
background-color: #ff9999;
position: absolute;
top: 50px;
left: 50px;
z-index: -1;
}
</style>
</head>
<body>
<div class="parent">
z-index auto
<div class="child">z-index -1</div>
</div>
</body>
</html>
なんでこうなるのか?
キーワードは**「スタックコンテキスト(スタック文脈)」**
z-indexについてのw3cの仕様を見てみると
位置指定されるボックスに対して、'z-index'プロパティは以下を指定する:
- 現在のスタックコンテキストにおけるボックスのスタックレベル。
- ボックスがスタックコンテキストを設置するかどうか。
値は次の意味を持つ:
integer
この整数値は、現在のスタックコンテキストにおける生成ボックスのスタックレベルである。ボックスはまた、新しいスタックコンテキストを設置する。
auto
現在のスタックコンテキストにおける生成ボックスのスタックレベルは0になる。ボックスが'position: fixed'である場合、またはボックスがルートである場合、ボックスはまた、新しいスタックコンテキストを設置する。
なるほど、わからん...
かいつまんでいうと、z-indexの指定は同じスタックコンテキスト内での順番(スタックレベル)を指定するものになるので、スタックコンテキストが違う場合は意図した通りに設定されない可能性があります。
スタックコンテキストを生成するパターンとして
-
position: relative
またはposition: absolute
でz-index: auto
以外を指定 -
position: fixed
またはposition: sticky
を指定 -
opacity: 1
以外を指定 -
transform: none
以外を指定
この辺を指定した場合はz-indexが意図した通りにならない可能性があります!
z-index: 0
とz-index: auto
は意味が違うから気をつけて!
スタックコンテキストについては下記記事が詳しいよ
z-index再入門
z-index とスタックコンテキスト