見出し画像

Why is your z-index not working again? 階層は一体どうなっているの?

みなさんこんにちは!
ワンキャリアでエンジニアを担当しているコ ショウトウ(GitHub:jamesdongdong)です!

突然ですが、皆さんz-indexを理解できていますか?
ご存知の通り、z-indexは要素の重なりの順序を決めるものですが、しばしば意図通りに設定できないことがあります。
皆さんの中にも『あれ、なんでz-indexが効かないんだ』と思っているエンジニアの方がいらっしゃるかもしれません。そんな方達に向けて、今回はz-indexとHTML階層について説明します!



z-indexとは

z-indexは、CSSのプロパティの1つで、要素の表示優先順位を制御するために使用されます。大きいz-index値を持つ要素は、小さいz-index値を持つ要素よりも上に表示されます。

MDNで簡単なDEMOを試すことができます。

z-indexの値を大きくするだけで、該当する要素が上層に配置されるように見えます。しかし、本当にそれだけなのでしょうか?以下の問題を見てみましょう。

問題1 

z-index 2のbox2がz-index 1のcontentの下にあるのはなぜか?

問題2

z-index 5のbox2-3がz-index 2のcontentの下にあるのはなぜか?

z-indexが全然効いてないですね(笑)。これから、z-indexの有効条件について説明します。


解説

z-indexが有効になる条件

z-indexが効果的に適用される前提条件は、z-indexを使用する要素がStacking Contextを生成できることです。
Stacking Contextを簡単に説明すると、高層建築物に似ています。
まず、<html>要素は基礎となります。すべての建物はこの基礎から建てられます。
そして、Stacking Contextが生成されるたびに、それは建物を建てることに相当し、z-indexの値は建物の高さに相当します。

Stacking Contextを生成できる要素

以下の要素はStacking Contextを生成でき、z-indexの値が有効になります

  1. 要素のpositionがfixed / stickyの場合

  2. 要素のpositionがabsolute / relativeで、z-indexがauto以外の場合

  3. 要素がflex / gird の子要素で、z-indexがauto以外の場合

  4. 要素にopacityが設定され、その値が1未満の場合

  5. 要素に以下のいずれかが設定され、その値がnone以外の場合

    1. transform

    2. filter

    3. perspective

    4. clip-path

    5. mask / mask-image / mask-border

  6. etc...

より詳細な説明は、以下を参考にしてください。

この知識があれば、問題1を解明することができます。

ソースコードを見ると、Box 2 はStacking Contextを生成できない要素であるため、設定されたz-index も無効であることがわかります。一方、Content要素は、transformというプロパティを使用してStacking Contextを生成できます。これは高さ1メートルの建物(z-index: 1)を建てているのと同じです。その結果、Content要素がBox 2要素の上に配置されるわけです。


z-indexが親子関係に影響される

z-indexが有効になった後、z-indexが大きくなればなるほど、要素が上に配置されるように見えますが、実際は必ずしもそうではありません。その理由は、z-indexは親要素のz-indexにも影響を受けるからです。

実は、Stacking Contextはネストすることが可能です(最も見落としやすいポイントです)。
「ネストする」とは、1つのStacking Context内に別のStacking Contextを作成できるということです。ネストされたStacking Contextでは、子要素Stacking Contextは親要素Stacking Context内に制約されて、子要素Stacking Contextのz-index値がいかに大きくても、親要素Stacking Contextの高さを超えることはできません。

問題2を見直してみましょう。Box 2とContent要素は両方ともStacking Contextを生成でき、Box 2のz-indexが小さいため、Box 2はContentの下にあります。Box 2-3はBox 2の上に新たなStacking Contextを作成しますが、Box 2のコンテキスト内にあるため、Box 2-3のz-indexがいかに高くても、Box 2を超えることはできず、当然ながらContentの上に現れることもできません。


おわりに

用意した2つの問題の説明は以上になりますが、z-indexを理解することができましたか?この記事が皆さんのz-indexに関する疑問を解消できれば幸いです。
ここまで読んでいただき、ありがとうございました。


おまけ

コードだけを見ても、ページの階層構造を理解するのは難しいですね。
以下の視覚化ツールを使えば、階層が実際にどのように構築されているかをもっと直感的に理解できるかもしれません。是非使ってみてください。

  • Microsoft Edge の develop tool の3D Viewで (引用元:Yahoo! JAPAN)

  • Google Chrome のdevelop tool のLayersで (引用元:Yahoo! JAPAN)


▼ワンキャリアのエンジニア組織のことを知りたい方はまずこちら

▼カジュアル面談を希望の方はこちら

▼エンジニア求人票


この記事が参加している募集

オープン社内報

この記事が気に入ったらサポートをしてみませんか?