Edited at

z-indexが言うことを聞いてくれない場合はこの辺のことが原因だと思うよ

More than 1 year has passed since last update.

z-indexをつかって要素の順番を変えていたのですが、どうにも思った通りにいかないことがありました。

今回はそんなハマったパターンになります。


親子関係になっているタグで親要素に z-index: auto 以外の値を指定した場合

スクリーンショット 2017-06-12 18.59.37.png

<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以外を指定した場合

スクリーンショット 2017-06-12 19.09.05.png

<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をつけた場合

スクリーンショット 2017-06-12 19.14.44.png

<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指定した場合

スクリーンショット 2017-06-13 19.13.56.png

<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を指定した場合

スクリーンショット 2017-06-13 19.21.42.png

<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'プロパティは以下を指定する:

1. 現在のスタックコンテキストにおけるボックスのスタックレベル。

2. ボックスがスタックコンテキストを設置するかどうか。

値は次の意味を持つ:

integer

この整数値は、現在のスタックコンテキストにおける生成ボックスのスタックレベルである。ボックスはまた、新しいスタックコンテキストを設置する。

auto

現在のスタックコンテキストにおける生成ボックスのスタックレベルは0になる。ボックスが'position: fixed'である場合、またはボックスがルートである場合、ボックスはまた、新しいスタックコンテキストを設置する。


なるほど、わからん...

かいつまんでいうと、z-indexの指定は同じスタックコンテキスト内での順番(スタックレベル)を指定するものになるので、スタックコンテキストが違う場合は意図した通りに設定されない可能性があります。

スタックコンテキストを生成するパターンとして



  • position: relativeまたはposition: absolutez-index: auto以外を指定


  • position: fixedまたはposition: stickyを指定


  • opacity: 1以外を指定


  • transform: none以外を指定

この辺を指定した場合はz-indexが意図した通りにならない可能性があります!

z-index: 0z-index: autoは意味が違うから気をつけて!

スタックコンテキストについては下記記事が詳しいよ

z-index再入門

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