CSS Tips | 超実務コアCSSテクニック:レイアウト基礎 - z-index設計

Web APP CSS
スポンサーリンク

z-index は「どのレイヤーが手前に来るか」を決める番号

z-index は、要素の「前後関係(レイヤーの順番)」を数字でコントロールするためのプロパティです。
値が大きいほど手前、小さいほど奥に表示されます。

ただし、単純に「数字が大きければ勝ち」ではなく、
「どの“スタッキングコンテキスト”の中にいるか」で勝負の土俵が変わります。
ここを理解しておくと、z-index でハマることが一気に減ります。


z-index が効く前提条件と「スタッキングコンテキスト」

z-index が効くのは position がある程度指定されている要素

基本的に、z-index が意味を持つのは
position が relative / absolute / fixed / sticky の要素です。

.box {
  position: relative;
  z-index: 10;
}
CSS

position: static(デフォルト)のまま z-index を指定しても、
ブラウザによっては無視されたり、期待通りに動かなかったりします。
「前後関係を制御したい要素には position を付ける」
これは z-index 設計の前提として覚えておいてください。


スタッキングコンテキストという「レイヤーのグループ」

z-index は、同じ「スタッキングコンテキスト」の中でしか比較されません。
スタッキングコンテキストは、ざっくり言うと「レイヤーのグループ」です。

例えば、次のような要素は新しいスタッキングコンテキストを作ります。

.parent {
  position: relative;
  z-index: 0;      /* 多くのブラウザで新しいコンテキスト */
}

.modal {
  position: fixed;
  z-index: 50;
}

.dropdown {
  position: absolute;
  z-index: 20;
}
CSS

親ごとに「別のレイヤー世界」ができるイメージです。
その世界の中では z-index の大小で前後が決まりますが、
別の世界同士では「親同士の前後関係」が優先されます。

ここがわかっていないと
「z-index: 9999 にしたのに、まだ隠れるんだけど?」
という沼にハマりがちです。


例1:ヘッダー、ドロップダウン、モーダルのレイヤー設計

全体のレイヤーのイメージ

ヘッダー(固定)
ドロップダウンメニュー
モーダルのオーバーレイと本体

このあたりは、レイヤーの優先順位をあらかじめ決めておくと設計が楽になります。

例えば、こういう優先度にします。

ヘッダーよりモーダルが上
モーダルの中のコンテンツよりオーバーレイが下
ドロップダウンはヘッダーの上

これを z-index に落とし込んでみます。


CSS 版

.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 56px;
  background: #0f172a;
  color: #e5e7eb;
  z-index: 20;
}

.header-menu {
  position: absolute;
  top: 100%;
  right: 16px;
  background: #ffffff;
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(15,23,42,0.25);
  z-index: 30;
}

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15,23,42,0.5);
  z-index: 40;
}

.modal {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
}
CSS
<header class="header">
  ヘッダー
  <div class="header-menu">
    メニュー
  </div>
</header>

<div class="modal-overlay"></div>
<div class="modal">
  <div class="modal-content">
    モーダル本体
  </div>
</div>
HTML

ここでは、
ヘッダー 20
ヘッダーメニュー 30
モーダルオーバーレイ 40
モーダル本体 50

というレイヤー構造になっています。


Tailwind 版

Tailwind にはあらかじめ z-index のユーティリティが用意されています。

z-0, z-10, z-20, z-30, z-40, z-50 などです。

<header class="fixed top-0 left-0 right-0 h-14 bg-slate-900 text-slate-100 z-20">
  ヘッダー
  <div class="absolute top-full right-4 mt-2 bg-white rounded-lg shadow-lg z-30">
    メニュー
  </div>
</header>

<div class="fixed inset-0 bg-slate-900/50 z-40"></div>

<div class="fixed inset-0 flex items-center justify-center z-50">
  <div class="bg-white p-6 rounded-lg w-80">
    モーダル本体
  </div>
</div>
HTML

Tailwind の z-index は「段階的なレイヤー設計」に向いています。
大きな単位で 10, 20, 30… と分けておくと、後から調整しやすくなります。


例2:カードの中で「バッジやオーバーレイ」を前面に出す

CSS 版

.card {
  position: relative;
  background: #ffffff;
  border-radius: 12px;
  overflow: hidden;
}

.card-image {
  position: relative;
  z-index: 0;
}

.card-badge {
  position: absolute;
  top: 12px;
  left: 12px;
  background: #ef4444;
  color: #ffffff;
  padding: 4px 8px;
  border-radius: 9999px;
  font-size: 12px;
  z-index: 10;
}

.card-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(15,23,42,0.7), transparent);
  z-index: 5;
}
CSS
<div class="card">
  <div class="card-image">
    <img src="photo.jpg" alt="">
  </div>
  <div class="card-overlay"></div>
  <span class="card-badge">NEW</span>
</div>
HTML

ここでは、
画像 0
オーバーレイ 5
バッジ 10

という順番でレイヤーを重ねています。
「どれを一番手前に見せたいか」を数字で表現しているイメージです。


Tailwind 版

<div class="relative bg-white rounded-xl overflow-hidden">
  <div class="relative z-0">
    <img src="photo.jpg" alt="" class="w-full h-48 object-cover">
  </div>

  <div class="absolute inset-0 bg-gradient-to-t from-slate-900/70 to-transparent z-10"></div>

  <span class="absolute top-3 left-3 bg-red-500 text-white text-xs px-2 py-1 rounded-full z-20">
    NEW
  </span>
</div>
HTML

Tailwind では z-0, z-10, z-20 のように段階を分けておくと、
「どれが一番手前か」が視覚的にもわかりやすくなります。


例3:position と z-index の組み合わせでハマりやすいパターン

親の z-index が子の限界を決めてしまう

例えば、こんな構造を考えます。

.parent-a {
  position: relative;
  z-index: 10;
}

.parent-b {
  position: relative;
  z-index: 5;
}

.child-of-b {
  position: absolute;
  z-index: 9999;
}
CSS
<div class="parent-a">
  A
</div>

<div class="parent-b">
  <div class="child-of-b">
    Bの子
  </div>
</div>
HTML

この場合、
どれだけ child-of-b の z-index を大きくしても、
parent-a の上には出られません。

理由は、
parent-aparent-b がそれぞれ別のスタッキングコンテキストを作っていて、
その「親同士の z-index の勝負」が先に決まってしまうからです。

このようなときは、
本当に z-index を付けるべきなのは「子」ではなく「親」だと気づけると、設計がスッキリします。


Tailwind での同じ状況

<div class="relative z-10 bg-blue-100 p-4">
  A
</div>

<div class="relative z-5 bg-red-100 p-4">
  <div class="absolute z-[9999] bg-red-500 text-white p-2">
    Bの子
  </div>
</div>
HTML

見た目としては、
A が常に B の子より手前に来ます。
z-[9999] のような大きな値を子に付けても、
親の z-5 の「世界の中」でしか戦えないからです。


Tailwind の z-index 設計の考え方

Tailwind には、デフォルトでいくつかの z-index レベルが用意されています。

z-0, z-10, z-20, z-30, z-40, z-50

これを「レイヤーの階層」としてざっくり決めておくと、設計が楽になります。

例えば、こんな感じのレイヤー設計がよく使われます。

z-0〜z-10
通常のコンテンツ、カード内のオーバーレイなど

z-20
固定ヘッダー、固定フッターバー

z-30
ドロップダウンメニュー、ツールチップ

z-40
モーダルのオーバーレイ

z-50
モーダル本体、最前面に出したい UI

Tailwind では、どうしても中間の値が欲しいときは z-[15] のように任意値も使えますが、
基本は用意されたステップの中で設計した方が、チーム開発では混乱が少ないです。


実務での「z-index 設計」のコツ(ここが一番大事)

z-index は「その場しのぎで数字を盛る」とすぐにカオスになります。
なので、最初にざっくりと「レイヤーのルール」を決めておくのが大事です。

例えば、こんな考え方です。

まず、大きなレイヤーの種類を決める。
ベースコンテンツ
ナビゲーション
ポップアップ系(ドロップダウン、ツールチップ)
モーダル

それぞれに「だいたいこのあたりの z-index を使う」と決めておく。
ベース 0〜10
ナビ 20
ポップアップ 30
モーダル 40〜50

こうしておくと、
「このコンポーネントはどのレイヤーに属するか?」を考えるだけで、
自然と z-index の値が決まっていきます。

そしてもうひとつ大事なのは、
「本当に z-index が必要か?」を毎回疑うことです。

position の指定や HTML の順番、スタッキングコンテキストの整理だけで解決できるなら、
z-index を増やさない方が、長期的にはきれいな設計になります。


まとめ

z-index は

要素の前後関係を数字で制御するためのプロパティで、
position とスタッキングコンテキストとセットで考える必要があります。

CSS では

position: relative;
z-index: 10;
CSS

Tailwind では

class="relative z-10"
HTML

のように使います。

ヘッダー、ドロップダウン、モーダル、オーバーレイ、ツールチップなど、
「どれを手前に見せたいか」を意識して、
レイヤーごとに z-index の“帯”を決めておくと、
レイアウトがぐっと安定します。

タイトルとURLをコピーしました