106
78

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

いつから、z-indexがpositionだけのものだと錯覚していた?

Last updated at Posted at 2020-02-25

タイトルの元ネタになっている『BLEACH』は読んだことありません。

悩ましいz-index問題

CSSを学んだことある人なら一度は通るz-index問題。単純にz-indexの値で重なりが決まるのではなく、親要素との関係によって重なりが変わるので複雑です。ついz-index: 9999はやってしまいます。(一番上なんだな、っていうのが分かりやすいので良いとは思いますが)

これが問題になるのはpositionのプロパティを使ったときが多いですが、position以外にもz-indexが有効になるプロパティがあります。

具体例がこちら↓

See the Pen z-index by Nishihara (@Nishihara) on CodePen.

この記事ではHTMLは以下のようにidの小さい方から書かれている前提になります。

<section class="section section1">
  <div id="block1">z-index: 3</div>
  <div id="block2">z-index: 2</div>
  <div id="block3">z-index: 1</div>
</section>

display: flexの時

display: flexを使った際の子要素も実はz-indexが有効になります。flexだけを使って重ねるというのは、あまりない場面かもしれませんが、ネガティブマージンを使って重ねるとz-indexが効いているのが分かります。

.section1 {
  display: flex;
  justify-content: flex-start;
}

#block1 {
  background-color: rgb(228, 100, 100);
  z-index: 3;
}

#block2 {
  background-color: rgb(100, 228, 100);
  z-index: 2;
  margin-top: 40px;
  margin-left: -80px;
}

#block3 {
  background-color: rgb(100, 100, 228);
  z-index: 1;
  margin-top: 80px;
  margin-left: -80px;
}

display: gridも

flexと同様にdisplay: gridでもz-indexが使えます。そもそもgridでレイアウトを重ねることは少ないと思いますが。。。

.section2 {
  display: grid;
  justify-content: flex-start;
  grid-template:
    "block1 block2 block3" 120px /
    120px 120px 120px;
}

#block4 {
  background-color: rgb(228, 100, 100);
  z-index: 3;
}

#block5 {
  background-color: rgb(100, 228, 100);
  z-index: 2;
  margin-top: 40px;
  margin-left: -80px;
}

#block6 {
  background-color: rgb(100, 100, 228);
  z-index: 1;
  margin-top: 80px;
  margin-left: -160px;
}

組み合わせても有効になる

これらも要素にz-indexが有効であることを知らなくても、それぞれを単体で使う場合にはそんなに問題はありません。問題になってくるのは、positionやこれらを組み合わせた時です。

例えば下記のように、flexで並べて、子要素にposition: absoluteを使って配置し、transform: translateで重ねた場合はどうでしょう?その場合もz-indexの値が効いてきます。

.section3 {
  display: flex;
  position: relative;
  justify-content: flex-start;
}

#block7 {
  background-color: rgb(228, 100, 100);
  z-index: 3;
}

#block8 {
  background-color: rgb(100, 228, 100);
  z-index: 2;
  position: absolute;
  top: 40px;
  left: 40px;
}

#block9 {
  background-color: rgb(100, 100, 228);
  z-index: 1;
  transform: translate(-40px, 80px);
}

この場合は、#block7が一番上にきます。

z-indexパズル

z-indexを指定しない場合は重ね合わせコンテキストのルールに従って、HTMLで後に書かれているものが上になります。では、次のような場合どうでしょう。

.section4 {
  display: flex;
  position: relative;
  justify-content: flex-start;
}

#block10 {
  background-color: rgb(228, 100, 100);
}

#block11 {
  background-color: rgb(100, 228, 100);
  position: relative;
  margin-top: 40px;
  margin-left: -80px;
}

#block12 {
  background-color: rgb(100, 100, 228);
  margin-top: 80px;
  margin-left: -80px;
}

子要素にはz-indexが指定されていません。なのでHTMLで一番最後の要素の#block12が一番上に来そうですが、実はそうではありません

よく見ると、#block11にはposition: relativeが指定されています。そうすると、新たに重ね合わせコンテキストが発生するので#block11が一番上にきます。しかしここに、

#block10 {
  background-color: rgb(228, 100, 100);
  z-index: 1;
}

z-indexを指定すると通常の重ね合わせコンテキストを上書きするように#block10が一番上に来ます。ここまでくるとz-indexパズルですね!

最後に

重ね合わせがうまく行かなかったら、これらz-indexが有効なプロパティも疑ってみてください。より詳しいスタッキングコンテキストとz-indexの関係は『君は真に理解しているか?z-indexとスタッキングコンテキストの関係』もご参照ください。

106
78
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
106
78

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?