【CSS】z-indexが効かないときのチェックポイント3選

はじめに

初学者がはまりやすいCSSにz-indexがあります。

少し複雑なHTML構造になるといくらz-indexの数値を増減しても思い通りに重ならなず、途方にくれたことは誰もが一度はあるのではないでしょうか?

ここではそんなz-indexが効かないときに確認する3つのポイントを解説します。


position: static;

positionを指定しない場合の既定値はposition: static;ですが、これではz-indexを指定しても効いてくれません。

Static以外の値を指定することでこの問題を解決することができます。

z-indexが効かない:static

z-indexが効く  :relative absolute fixed sticky

特に位置を動かしたりする企図がない場合はposition: relative;を指定するのが無難ですね。


スタック文脈を考慮しましょう。

要素同士が横並びの兄弟要素であるときは問題なく効いてくれますが、子要素や疑似要素に効かせようとするときは親要素にz-indexを指定していないか確認しましょう。

下のように兄弟要素のみの場合は問題なく効いています。

<div class="sample">
    <div class="z-index-1"><span>z-index-1</span></div>
    <div class="z-index-2"><span>z-index-2</span></div>
    <div class="z-index-3"><span>z-index-3</span></div>
    <div class="z-index-4"><span>z-index-4</span></div>
</div>
<style>
    .sample > div > span {
        position: absolute;
        bottom: 0;
        left: 10px;
        width: 100%;
        color: #fff;
        font-size: 20px;
    }

    .sample {
        position: relative;
        height: 300px;
        transform: skew(-45deg);
    }

    .z-index-1,
    .z-index-2,
    .z-index-3,
    .z-index-4 {
        position: absolute;
        width: 200px;
        height: 100px;
    }

    .z-index-1 {
        top: 40px;
        left: 40px;
        background-color: rgba(255, 99, 71, 0.9);
        z-index: 4;
    }

    .z-index-2 {
        top: 80px;
        left: 80px;
        background-color: rgba(65, 105, 225, 0.9);
        z-index: 3;
    }

    .z-index-3 {
        top: 120px;
        left: 120px;
        background-color: rgba(138, 43, 226, 0.9);
        z-index: 2;
    }

    .z-index-4 {
        top: 160px;
        left: 160px;
        background-color: rgba(154, 205, 50, 0.9);
        z-index: 1;
    }
</style>
z-index-1
z-index-2
z-index-3
z-index-4

しかし、3つ目の要素の中に3-1のような子要素が含まれると逆になってしまいます。

<div class="sample">
    <div class="z-index-1"><span>z-index-1</span></div>
    <div class="z-index-2"><span>z-index-2</span></div>
    <div class="z-index-3">
        <span>z-index-3</span>
        <div class="z-index-3-1">
            <span>z-index-3-1</span>
        </div>
    </div>
</div>
<style>
    .z-index-1 {
        top: 40px;
        left: 40px;
        background-color: rgba(255, 99, 71, 0.9);
        z-index: 3;
    }

    .z-index-2 {
        top: 80px;
        left: 80px;
        background-color: rgba(65, 105, 225, 0.9);
        z-index: 2;
    }

    .z-index-3 {
        top: 120px;
        left: 120px;
        background-color: rgba(138, 43, 226, 0.9);
        z-index: 1;
    }

    .z-index-3-1 {
        top: 40px;
        left: 40px;
        background-color: rgba(154, 205, 50, 0.9);
        z-index: 0;
    }
</style>
z-index-1
z-index-2
z-index-3
z-index-3-1

ここで3-1を潜り込ませようとマイナス方向にz-indexをかけても変化がありません。

.z-index-3-1 {
        top: 40px;
        left: 40px;
        background-color: rgba(154, 205, 50, 0.9);
        z-index: -9999;/*これでも変化はありません*/
    }

これはz-indexを効かせた要素にはスタック文脈というz-indexのグループが生成されるためです。この状態では子要素にz-indexをかけても効かなくなってしまい、後ろの要素は原則に従って上に重ねられていきます。

(正確には子要素どうしの重なりに影響しています)

じゃあどうすれば?

子要素にz-indexを効かせるには、親要素がz-index: auto;である必要があります。

そのため子要素にz-indexを効かせたい親要素にz-index: auto;を設定した上で、そこを基準に周りのz-indexを決めていきます。

.z-index-3 {
    top: 120px;
    left: 120px;
    background-color: rgba(138, 43, 226, 0.9);
    z-index: auto;/*既定値なので指定しなくてもいいです*/
}

.z-index-3-1 {
    top: 40px;
    left: 40px;
    background-color: rgba(154, 205, 50, 0.9);
    z-index: -1;
}
z-index-1
z-index-2
z-index-3
z-index-3-1

ここで注意するのは、z-index: auto;とz-index: 0;は同じポジションに位置しますが、z-index: 0;ではスタック文脈を生成してしまう点です。


スタック文脈が生成されるのはz-indexだけではない!

ここでひとつ落とし穴が。

親要素にスタック文脈が生成される条件はz-indexだけではありません。

親要素に別のステータスがあっても効かなくなるCSSがいくつか存在します。

opacitytransformです。

.z-index-3 {
    top: 120px;
    left: 120px;
    background-color: rgba(138, 43, 226, 0.9);
    z-index: auto;
  transform: translateX(50px);/*スタック文脈が生成されてしまいます*/
}

.z-index-3-1 {
    top: 40px;
    left: 40px;
    background-color: rgba(154, 205, 50, 0.9);
    z-index: -1;
}

これを設定すると先程と同じく、子要素にマイナス方向のz-indexをかけても子要素が下に潜り込まなくなります。

z-index-1
z-index-2
z-index-3
z-index-3-1

※変化がわかりやすいようにanimationをつけています

z-indexやopacity・transformを使いたいときは

このスタック文脈を回避する方法としては、スタック文脈を作りたくない親要素を別の要素で囲んで、囲んだ要素にスタック文脈を生成するCSSを書き込むという方法があります。

<div class="sample">
	<div class="z-index-1"><span>z-index-1</span></div>
	<div class="z-index-2"><span>z-index-2</span></div>
	<div class="z-index-wrapper"><!-- このように別の要素で囲みます -->
		<div class="z-index-3">
			<span>z-index-3</span>
			<div class="z-index-3-1">
				<span>z-index-3-1</span>
			</div>
		</div>
	</div>
</div>
.z-index-wrapper {
   transform: translateX(50px);/*ここにCSSを配置します*/
}
.z-index-3 {
    top: 120px;
    left: 120px;
    background-color: rgba(138, 43, 226, 0.9);
    z-index: auto;
}

.z-index-3-1 {
    top: 40px;
    left: 40px;
    background-color: rgba(154, 205, 50, 0.9);
    z-index: -1;
}
z-index-1
z-index-2
z-index-3
z-index-3-1

まとめ

z-indexが効かないときは以下を確認してみましょう。

  • positionを指定しているか
  • 子要素に効かせたいときには親要素にz-index: auto;以外を設定していないか
  • 親要素にスタック文脈を生成するCSSを設定していないか(opacity・transform)

これを回避するためには、

  • Positionにstatic以外を指定する
  • z-indexを効かせたい要素の親要素にはz-index: auto;を指定する
  • 親要素にスタック文脈を生成するCSSを使いたいときは別の要素で囲んで、囲んだ要素にCSSを使用する

などの方法が挙げられます。
もし可能ならば、HTML構造を見直すことも視野に入れてもいいかもしれません。

複雑なz-indexを組むときには紙に書いたりコメントアウトで残すといいでしょう。
この記事が参考になって、思い通りの重なりが実現できたなら嬉しいです。

ではまた。

コメントを残す

メールアドレスが公開されることはありません。