0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WebフロントエンドAdvent Calendar 2024

Day 7

z-indexを設定しても前に出てこない?重ね合わせコンテキストとz-index

Posted at

z-indexを設定しても前に出てこない?

z-indexはCSSプロパティの1つで、要素の重なりの順を指定できます1
しかし、z-indexのみを要素に設定しても重なり順が変わらないことがあります。

z-indexがどのような状況の場合に重なり順を指定できるのかをみていきます。

z-indexが適用できる条件

z-indexposition:staticの要素に対しては適用できません。
positionabsolute,relative,fixed,stickyである要素や、flexアイテム、gridアイテムに対してz-index値が適用できます。

しかし、z-indexの数値が大きいものから順に前面に配置されるかというとそうではありません。
z-indexの値は重ね合わせコンテキストと呼ばれる空間内での順序を設定しているためです。

重ね合わせコンテキスト(Stacking Context)

重ね合わせコンテキスト(Stacking Context)とは、HTML要素の3次元的な重なり順を決定する、概念的な空間のことです。
要素は必ず最も近い祖先の重ね合わせコンテキストに属します。
また、重ね合わせコンテキストを生成した要素は、そのコンテキスト内で最背面に配置されます。

重ね合わせコンテキストが生成される条件はいくつかありますが、その中でも代表的なものとして、positionプロパティの設定があります。

  • positionabsoluteまたはrelativez-indexauto以外
  • positionfixedまたはsticky

これらの場合には重ね合わせコンテキストが生成されて、z-indexが適用できますが、position:static(デフォルト値)の場合には、z-indexによる指定ができません。

重ね合わせコンテキストの生成条件

positionの値以外に、以下のような条件でも重ね合わせコンテキストが生成されます(他にもあります)。

  • <html>(ルート要素)
  • opacity1未満
  • transformnone以外
  • filternone以外
  • flexアイテムかgridアイテムでz-indexauto以外

z-index を大きくしても前に出てこない例

以下のようなケースを考えてみます。

<!DOCTYPE html>
<html>
<head>
    <link href="stacking_context.css" rel="stylesheet"/>
</head>
<body>
    <div class="div1">div 1</div>
    <div class="div2">
        div 2
        <div class="div3">div3</div>
    </div>
</body>
</html>
.div1{
    background-color: red;
    height: 80px;
    width: 240px;
    position: absolute;
    z-index: 10;
}
.div2{
    background-color: yellow;
    height: 120px;
    width: 280px;
    position: absolute;
    z-index: 1;
}
.div3{
    background-color: blue;
    height: 160px;
    width: 80px;
    position: absolute;
    z-index: 10000;
}

stacking_context.png

画像の赤い領域がdiv1、黄色い領域がdiv2、青い領域がdiv3に対応しています。

div1div2は兄弟要素であり、div3div2の子要素です。

設定しているz-indexは、

  • div1 z-index: 10;
  • div2 z-index: 1;
  • div3 z-index: 10000;

となっており、単純にz-indexの値を比較すると前面から順にdiv3,div1,div2と表示されるような気がします。

しかし、実際にはdiv1,div3,div2の順で表示されています。

これはz-indexが同一の重ね合わせコンテキスト内で比較される値であるからです。


この例では、重ね合わせコンテキストが4つ生成されています。

html
├── div1
└── div2
    └── div3

div1div2はルート要素の生成した重ね合わせコンテキストに属すため、z-index値の比較によってdiv1が前面にきます。

しかし、div3はルート要素の重ね合わせコンテキストには属さないため(div2の生成した重ね合わせコンテキストに属す)、div3div1のどちらが前面にくるかは、div3div1z-index値ではなく、div3の親要素であるdiv2div1z-index値の比較で決定されています。

div2div3については、同一の重ね合わせコンテキストに属さないため、z-indexによる比較はされません。
div2z-index値をdiv3のものより大きくなるように設定した場合でも、div3が前面にきます。
これは、重ね合わせコンテキストを生成した要素は、そのコンテキスト内で最も奥に配置されるためです2

さいごに

z-indexによって重なり順を指定するためには、position:staticでないことなどの条件があります。
また、条件を満たした場合でも、必ずしもz-indexの大きい順に前面にくるのではなく、重ね合わせコンテキスト同士の前後関係が関わってきます。
なぜか前面にこないという場合には、これらを疑ってみるとよさそうですね。

  1. z-indexzとはz軸のことです。画面上の水平方向がx軸、垂直方向がy軸、奥行きがz軸です。このz軸上での順番(index)を表すわけです。

  2. このため、html(ルート要素)が前面にくることもないわけですね。

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?