CreaTools LogoCreaTools
Tips

z-indexが効かない原因、99%はこの2つ

2026-01-30

結論:原因は2つしかない

  1. positionが指定されていない
  2. 親のstacking contextに閉じ込められている

z-indexを999にしても効かないのは、この2つのどちらか。


まず確認:positionはあるか

z-indexはpositionがないと効かない

/* 効かない */
.box {
  z-index: 100;
}

/* 効く */
.box {
  position: relative;
  z-index: 100;
}

static以外(relativeabsolutefixedsticky)ならOK。

確認方法

  1. DevToolsで対象要素を選択
  2. Computedタブを開く
  3. positionを検索
  4. staticならz-indexは無効

relativeを付けるだけで解決するケースが大半。


次に確認:stacking contextの罠

positionがあるのに効かない場合、親要素がstacking contextを作っている

<div class="parent" style="position: relative; z-index: 1;">
  <div class="child" style="position: relative; z-index: 9999;">
    ← これは親の外には出られない
  </div>
</div>

<div class="other" style="position: relative; z-index: 2;">
  ← こっちが上に来る
</div>

親のz-index: 1が壁になる。子がいくら大きな値を持っても、親の外には出られない。


stacking contextを作るプロパティ

これらが親にあると、子のz-indexは親の中で閉じる。

プロパティ条件
z-indexauto以外 + position指定
opacity1未満
transformnone以外
filternone以外
will-changetransformopacityなど
isolationisolate

特にtransformopacityは見落としやすい。

確認方法

  1. 対象要素の親を順番に確認
  2. 上記プロパティがあれば、それがstacking contextの境界
  3. 必要なら親のz-indexを調整するか、構造を変える

私がやらかした失敗

モーダルが背景より後ろに表示される。z-indexを99999にしても変わらない。

3時間悩んだ結果、親にtransform: translateZ(0)があった。GPU最適化のつもりで入れたコードが原因だった。

/* 親にこれがあった */
.modal-container {
  transform: translateZ(0); /* stacking contextが生まれる */
}

削除したら直った。


解決パターン早見表

症状原因対処
z-indexが完全に効かないposition: staticposition: relativeを追加
特定の要素より上に出られない親のstacking context親のz-indexを上げる or 構造変更
モーダルが後ろに隠れるtransform/opacityが親にある該当プロパティを削除 or モーダルをbody直下に移動

body直下に移動する解決策

親のstacking contextを変更できない場合、要素をbody直下に移動する。

// モーダルをbody直下に移動
document.body.appendChild(modalElement);

ReactならcreatePortalを使う。

import { createPortal } from 'react-dom';

function Modal({ children }) {
  return createPortal(
    <div className="modal">{children}</div>,
    document.body
  );
}

チェックリスト

□ position: static になっていない?
□ 親にz-index(auto以外)がある?
□ 親にtransformがある?
□ 親にopacity: 1未満がある?
□ 親にfilterがある?

この5つを確認すれば原因は特定できる。


まとめ

  • z-indexはposition必須(static以外)
  • 親のstacking contextを超えられない
  • transformopacityも壁になる
  • 構造を変えられないならPortalで解決