CSS 入門

CSS z-index 属性

CSSにおける z-index プロパティは、ウェブページ上で重なり合う要素のスタック順(重なり順)を制御するために使用されます。

z-index を指定しない場合、HTML内の記述順序によってどちらが前面に表示されるかが決まります。しかし、z-index を使用すれば、HTML構造に関係なくスタック順を明示的に定義できます。

複雑なレイアウトの作成、要素のオーバーラップ(重なり)の処理、そして特に absolutefixed ポジショニングを使用する際に、要素を意図した通りに表示させるために z-index の理解は不可欠です。これは要素の視覚的階層を管理し、重要なコンテンツが隠されないようにし、インタラクティブな要素へのアクセスを保証するのに役立ちます。

1. z-index プロパティの理解

z-index プロパティは、要素の「スタッキングコンテキスト(Stacking Context / 重なりコンテキスト)」内におけるスタックレベルを指定します。スタッキングコンテキストとは、観察者に向かって伸びる仮想のZ軸に沿ったHTML要素の三次元的な概念であり、優先順位の階層を表します。簡単に言えば、要素が重なったときに「誰が前で、誰が後ろか」を決定します。

1.1 z-index の基礎

  • 値:z-index は整数値(正の数、負の数、0)および auto を受け入れます。
  • デフォルト値:z-index のデフォルト値は auto です。
  • 適用対象:z-index はポジショニングされた要素(つまり position の値が relativeabsolutefixed、または sticky である要素)に対してのみ有効です。デフォルトの static 配置の要素に適用しようとしても、効果はありません。
  • スタック順:より大きな z-index 値を持つ要素が、より小さな値を持つ要素の前面に表示されます。
  • コンテキストの重要性:要素の z-index は、そのスタッキングコンテキスト内でのみ意味を持ちます。つまり、ある要素の z-index は、同じスタッキングコンテキスト内にある他の要素としか比較されません。

2. スタッキングコンテキスト (Stacking Contexts) 詳解

スタッキングコンテキストは、以下のいずれかの方法で形成されます。

  • ルート要素 (<html>):ドキュメント全体の基礎となるスタッキングコンテキストです。
  • ポジショニング要素かつ z-indexauto 以外:positionstatic 以外で、z-index に具体的な数値が設定されている要素。これが新しいスタッキングコンテキストを作成する最も一般的なケースです。
  • 特定のCSSプロパティを持つ要素:明示的な z-index がなくても、特定のプロパティによって新しいスタッキングコンテキストが作成されます。例:
    • opacity が 1 未満
    • transformfilterperspectivenone 以外
    • isolation: isolate
    • mix-blend-modenormal 以外
    • will-change で上記いずれかの属性が指定されている

z-index: auto の挙動:要素の positionrelative / absolute / fixed であっても、z-indexauto の場合は新しいスタッキングコンテキストを作成しません。その要素は親のスタッキングコンテキストに参加します。

3. z-index と兄弟要素

要素が兄弟関係(同じ親を共有)にあり、かつ同じスタッキングコンテキストに属している場合:

  • 高い z-index が優先:z-index: 2 の要素は z-index: 1 の要素の上に表示されます。
  • z-index が同じならソース順:2つの兄弟要素が同じ z-index 値(または共に auto)である場合、HTMLソースコード中で後に記述された要素が上に重なります。これがデフォルトの自然なスタック挙動です。

4. 実戦的なサンプル

4.1 示例 1:z-index の基本用法

以下のHTMLを考えてみましょう。

<div class="container">
  <div class="box box1">Box 1</div>
  <div class="box box2">Box 2</div>
</div>
.container {
  position: relative; /* スタッキングコンテキストを作成 */
  width: 200px;
  height: 200px;
}

.box {
  position: absolute;
  width: 100px;
  height: 100px;
}

.box1 {
  background-color: rgba(255, 0, 0, 0.5); /* レッド、透明度 50% */
  top: 20px;
  left: 20px;
  z-index: 1;
}

.box2 {
  background-color: rgba(0, 0, 255, 0.5); /* ブルー、透明度 50% */
  top: 40px;
  left: 40px;
  z-index: 2;
}

解析:
この例では、.containerposition: relative を持っているため、スタッキングコンテキストを確立しています。.box1.box2 はコンテナ内で絶対配置されています。.box2z-index (2) は .box1 (1) よりも高いため、.box2(青いボックス)が .box1(赤いボックス)の上に表示されます。

4.2 示例 2:負の値の z-index

負の z-index 値を使用して、要素を親要素の背後に配置できます。先ほどの例を修正してみましょう。

.container {
  position: relative;
  width: 200px;
  height: 200px;
  background-color: yellow; /* 観察しやすくするために背景色を追加 */
}

.box {
  position: absolute;
  width: 100px;
  height: 100px;
}

.box1 {
  background-color: rgba(255, 0, 0, 0.5);
  top: 20px;
  left: 20px;
  z-index: -1; /* 負の z-index */
}

.box2 {
  background-color: rgba(0, 0, 255, 0.5);
  top: 40px;
  left: 40px;
  z-index: 2;
}

解析:
現在、.box1z-index: -1 を持っています。これは、.container 要素自体の背後に配置されることを意味します(当然 .box2 の後ろでもあります)。赤いボックスはコンテナの黄色い背景の裏側に隠れます。もしコンテナに背景色がなければ、赤いボックスはあたかも「消えた」ように見えるか、さらに下層の背景の上に配置されているように見えます。

4.3 示例 3:スタッキングコンテキストと入れ子要素

スタッキングコンテキストは入れ子(ネスト)にすることができます。より複雑なシナリオを見てみましょう。

<div class="container">
  <div class="box box1">Box 1</div>
  <div class="box box2">
    Box 2
    <div class="inner-box">Inner Box</div>
  </div>
</div>
.container {
  position: relative;
  width: 200px;
  height: 200px;
}

.box {
  position: absolute;
  width: 100px;
  height: 100px;
}

.box1 {
  background-color: rgba(255, 0, 0, 0.5);
  top: 20px;
  left: 20px;
  z-index: 1;
}

.box2 {
  background-color: rgba(0, 0, 255, 0.5);
  top: 40px;
  left: 40px;
  z-index: 2;
}

.inner-box {
  position: relative; /* スタッキングコンテキストを作成 */
  background-color: rgba(0, 255, 0, 0.5);
  width: 50px;
  height: 50px;
  top: 25px;
  left: 25px;
  z-index: 3;
}

解析:
ここでは、.box2z-index.box1 よりも高いため、.box2 が上に表示されます。
しかし、.inner-box.box2 の内部に位置し、position: relativez-index: 3 を持っています。

.inner-boxposition: relative は、.box2内部に新しいスタッキングコンテキストを作成します。.inner-box に指定された z-index: 3 は、あくまでこの .box2 が作ったスタッキングコンテキスト内でのみ有効です。

したがって、この z-index: 3 がどれほど大きくても、.box1.box2 本来の重なり順には影響しません。内部ボックスは .box2 内の他のどのコンテンツよりも上に表示されますが、.box2 自体は依然として .box1 の上に留まります。