Skip to content

z-indexとスタックコンテキストを確認する

先日、「z-index: 1;」を指定した要素が「z-index: 999;」を指定した要素よりも手前に表示されるという事象に遭遇しました。

調べているうちにスタックコンテキスト(スタック文脈)という仕様によるものだということがわかったのでまとめておきたいと思います。

参考サイト:https://developer.mozilla.org/ja/docs/Web/CSS/Understanding_z_index

z-index の役割

私はこれまで z-index の役割について、
「ページ内で値の大きいものが手前になる」
というくらいに思っていました。

ところがどうやら z-index にはより複雑な仕様があり、
「スタックコンテキストの内部の積み重なり順序を制御する」
というような役割を果たしていることがわかってきました。

z-index を指定しない場合

z-index を指定しない場合、要素は次のような順序で積み重なります。

【積み重なり順序】

  1. ルート要素
  2. 子孫ブロック要素
  3. float 指定された子孫要素
  4. 子孫インライン要素
  5. position 指定された子孫要素

※同じレイヤーでは、HTML 内の出現順に奥から手前に積み重なります。

なかなかに複雑ですが、
「背景が一番奥、各要素がその手前、float や position が指定されている要素はさらに手前」
という順序を理解できれば問題ありません。

また、子と孫が「子孫ブロック」としてひとまとまりになっていることもポイントです。要素のネスト構造と積み重なり順序には直接的な関係はありません。

スタックコンテキスト

要素がある条件を満たすと、その要素はスタックコンテキスト(スタック文脈)を形成します。

そして要素がスタックコンテキストを形成するとその子孫要素に、前述の積み重なり順序が適用されます。

このとき兄弟の関係にあるスタックコンテキストの内部の積み重なり順序は、スタックコンテキストごとに独立して決定されるという性質があります。

スタックコンテキストが作られる条件はいろいろと細かく決まっているのですが、代表的なものを紹介します。

【スタックコンテキストを形成する条件】

  • html 要素
  • position: absolute; & z-index が auto 以外
  • position: relative; & z-index が auto 以外
  • position: fixed;
  • position: sticky;
  • display: flex; の子要素 & z-index が auto 以外
  • opacity が 1 未満
  • transform が none 以外
  • その他

これらの条件を満たした要素は自身をルート要素とした新たなスタックコンテキストを形成するため、その内部に前述の積み重なり順序が適用されます。

z-index を指定する場合

z-index が指定されている場合、積み重なり順序は次のようになります。

【積み重なり順序(z-index を指定する場合)】

  1. ルート要素
  2. position 指定され、z-index に負の値が指定されている要素
  3. 子孫ブロック要素
  4. float 指定された子孫要素
  5. 子孫インライン要素
  6. position 指定され、z-index に auto または 0 が指定されている要素
  7. position 指定され、z-index に正の値が指定されている要素

z-index を指定された要素は通常の子孫ブロック要素に対して、負の値を指定されると奥、auto, 0, 正の値を指定されると手前に表示されます。

例題

たとえばこのように z-index を指定したとします。

スタックコンテキストの理解がないと div#d4 が最も手前になると思ってしまうかもしれません。

ところがスタックコンテキストを理解していれば、次のように正しく判断することができます。

div#d2 が最も手前になります。

Comments are closed.