できない.dev

CSSでz-index が効かないときに重なり順を直すには

z-index を指定しても要素が前に出ないときの 2 大原因、position の指定漏れと親が作る重なりの文脈を、描画の比較で確かめて直す方法を示す。

公開:

プレビュー
<div class="stage"><div class="box a">A(z-index: 2)</div><div class="box b">B(z-index: 1)</div></div>
.stage {
  padding: 8px 0;
  font: 14px system-ui;
}
.box {
  width: 150px;
  height: 56px;
  padding: 8px;
  box-sizing: border-box;
  color: #fff;
}
.a {
  background: #ea580c;
  position: relative;
  z-index: 2;
}
.b {
  background: #2563eb;
  margin: -24px 0 0 60px;
  padding-top: 30px;
  z-index: 1;
}

z-index は position が static 以外の要素に効くので、前に出したい要素に position: relative を足す。
それでも負けるときは、親が作る重なりの文脈が原因なので、数字を上げるより親の z-index を直す。

position が static のままだと効かない

z-index は、position が relative・absolute・fixed・sticky のいずれかの要素にだけ効く。

何も指定していない要素(position: static)に z-index を書いても無視される。

そのため、DOM の後ろにある要素が前面に描かれる。

前に出したい要素に position: relative を足せば、見た目を変えずに z-index が効くようになる。

なお flex や grid の子は、position がなくても z-index が効く。

できない例: z-index だけ(A が B の下に隠れる)
.stage {
  padding: 8px 0;
  font: 14px system-ui;
}
.box {
  width: 150px;
  height: 56px;
  padding: 8px;
  box-sizing: border-box;
  color: #fff;
}
.a {
  background: #ea580c;
  z-index: 2;
}
.b {
  background: #2563eb;
  margin: -24px 0 0 60px;
  padding-top: 30px;
  z-index: 1;
}
できる例: position: relative を足す(A が前に出る)
.stage {
  padding: 8px 0;
  font: 14px system-ui;
}
.box {
  width: 150px;
  height: 56px;
  padding: 8px;
  box-sizing: border-box;
  color: #fff;
}
.a {
  background: #ea580c;
  position: relative;
  z-index: 2;
}
.b {
  background: #2563eb;
  margin: -24px 0 0 60px;
  padding-top: 30px;
  z-index: 1;
}

z-index を上げても親の外へ出られない

position と z-index を持つ要素は、自分の中身をひとまとめにした「重なりの文脈」を作る。

中の子要素は、z-index: 9999 でもその文脈の内側でしか順位を競えない。

親の順位が兄弟より低いなら、子は兄弟の下に隠れたままになる。

子の数字を上げ続けるのではなく、原因の親の z-index を兄弟より大きくする。

できない例: 親が z-index: 1(メニューがカード 2 の下に隠れる)
.card {
  position: relative;
  width: 220px;
  height: 60px;
  padding: 8px;
  box-sizing: border-box;
  font: 14px system-ui;
}
.one {
  background: #f1f5f9;
  border: 1px solid #cbd5e1;
  z-index: 1;
}
.two {
  background: #bae6fd;
  z-index: 2;
}
.menu {
  position: absolute;
  top: 44px;
  left: 20px;
  padding: 8px 10px;
  background: #ea580c;
  color: #fff;
  z-index: 9999;
}
できる例: 親を z-index: 3 にする(メニューが前に出る)
.card {
  position: relative;
  width: 220px;
  height: 60px;
  padding: 8px;
  box-sizing: border-box;
  font: 14px system-ui;
}
.one {
  background: #f1f5f9;
  border: 1px solid #cbd5e1;
  z-index: 3;
}
.two {
  background: #bae6fd;
  z-index: 2;
}
.menu {
  position: absolute;
  top: 44px;
  left: 20px;
  padding: 8px 10px;
  background: #ea580c;
  color: #fff;
  z-index: 9999;
}

重なりの文脈を作ってしまう指定

position と z-index の組み合わせ以外にも、次の指定は親を重なりの文脈にする。

  • opacity が 1 未満
  • transform・filter・clip-path などの指定
  • isolation: isolate

見覚えのない指定が親にないかを開発者ツールで順にたどると、原因の親が見つかる。

コンポーネントの内側だけで順位を完結させたいときは、親に isolation: isolate を付けて文脈を意図的に作る。