HTML / CSS公開 約8分

z-indexが効かないとき:子の数字より親の重なり順を見る

z-indexを999にしても案内が隣の箱の後ろへ隠れる場合は、親の重なり順を調べます。架空の会場案内を使い、スタッキングコンテキストと切り抜きを区別し、変更する要素を選びます。

この記事の目次
  1. 999と2を、直接比較できるとは限らない
  2. 隠れる状態を一枚のHTMLで再現する
  3. 子の値を戻し、親を一段上げて比べる
  4. 端で切れている場合は、重なり順を変えても直らない
  5. 数字を変える前に、直す範囲を決める
  6. 四つの状態を、同じ場所で確かめる

案内の箱にz-index: 999を指定したのに、隣の箱が前に出る。値を1000へ増やしても変わらないなら、比べる相手を間違えているかもしれません。z-indexが効かないように見える場面では、その箱だけでなく、親がどの順序で重なっているかを確認します。

HTMLの親子関係とCSSのクラス指定を読める人向けに、架空の会場案内を二つの箱で再現します。エディターとブラウザーを用意してください。モーダルの開閉やメニューの操作は作らず、普通の要素同士の前後関係に絞った練習です。

999と2を、直接比較できるとは限らない

スタッキングコンテキストは、要素の重なり順を扱うまとまりです。親がそのまとまりを作っていると、中の子に大きな数字を付けても、親の外にいる要素との順序を直接決められません。

今回、案内を包む親はz-index: 1、別の箱はz-index: 2です。案内自身は999でも、まず外側で1と2が比較され、親ごと後ろに配置されます。子の999は、ページ全体で使う通し番号ではありません。

MDNのスタッキングコンテキストの解説でも、子のまとまりは親の中で独立して扱われます。たとえば親を3へ変えると、外側の比較は3と2になり、子の999を変更せずに前後が変わります。

次の図は、この二つの条件を同じ配置で比べた模式図です。今回の修正で前へ出るのは案内だけではなく、それを含む親のまとまり全体である点に注目してください。

変更前は親1の中の案内が隣の2より後ろ。変更後は親を3へ変え、子の999はそのままで案内が前に出る

隠れる状態を一枚のHTMLで再現する

次をlayers.htmlとして保存し、ブラウザーで開きます。色は二つの箱を見分けるためのものです。重なる部分を観察できるよう、絶対配置で意図的に位置をずらしています。

<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>会場案内の重なり|練習</title>
<style>
* { box-sizing: border-box; }
body { margin: 1rem; font-family: sans-serif; line-height: 1.7; color: #222; }
main { max-width: 36rem; margin-inline: auto; }
.stage { position: relative; height: 270px; border: 2px solid #333; }
.guide-group { position: relative; z-index: 1; height: 240px; }
.guide {
  position: absolute; z-index: 999;
  top: 40px; left: 16px; right: 16px;
  min-height: 120px; padding: 16px;
  background: #ffe0c6; border: 2px solid #9c421b;
}
.neighbor {
  position: absolute; z-index: 2;
  top: 110px; left: 48px; right: 8px;
  min-height: 120px; padding: 16px;
  background: #c9d9ee; border: 2px solid #29486b;
}
</style>
</head>
<body>
<main>
<h1>会場案内(架空の練習)</h1>
<div class="stage">
  <div class="guide-group">
    <div class="guide">案内:入口は建物の右側です。</div>
  </div>
  <div class="neighbor">隣の箱:別のまとまりです。</div>
</div>
<p>箱が重なった部分の前後を比べます。</p>
</main>
</body>
</html>

開いた直後は、青い隣の箱がオレンジの案内の下半分に重なります。開発者ツールでguideを選び、計算済みのz-indexが999になっていることも確認します。値が適用されていないなら、先にCSSの適用元を調べる手順へ戻ります。

この例ではguide-groupにposition: relativeと整数のz-indexを組み合わせています。z-indexの説明で示される、新しいまとまりを作る条件の一つです。値がautoのrelativeまで、すべて同じ条件だとは考えないでください。

子の値を戻し、親を一段上げて比べる

最初の失敗を確かめるため、guideの999だけを9999へ変えて保存します。再読み込みしても、青い箱が前のままです。9999が小さいのではなく、外側の1と2が変わっていないのが原因です。

修正では子を999へ戻し、guide-groupのz-indexだけを3へ変更します。再読み込みするとオレンジの案内が前へ出ます。guideとneighborの位置や大きさは同じなので、移動で隠れ方をごまかしていないことも比較できます。

既存サイトで親を上げるときは、同じ親に含まれる別の要素も確認します。たとえば案内以外に写真やリンクが入っていれば、それらも同じまとまりとして前へ出る可能性があります。子だけを上げたい要件なら、要素を置く場所や親がまとまりを作る理由を見直す方が合う場合があります。

調査のメモは「guide=999、guide-group=1、neighbor=2。親を3へ変えると前後が逆転」と残せます。細かな数字を覚えるより、どの二つを同じ段階で比べたかを説明できることが大切です。

端で切れている場合は、重なり順を変えても直らない

二つ目は、後ろに隠れたように見えて、実際には親の端で切り抜かれている失敗です。親を3へ直した状態で、guideのrightを-24pxにし、stageへoverflow: hiddenを追加してください。案内の右側がstageの枠で切れます。

ここで親を30へ上げても、切れた部分は戻りません。overflowの説明にある領域外の切り抜きは、別の要素との前後関係とは違うためです。調べるのは「どの箱が手前か」ではなく「どの枠の外が消えているか」です。

今回の完成条件は案内をstage内へ収めることなので、rightを16pxへ戻します。overflow: hiddenを残したままでも、案内の右端が枠内に収まることを再確認できます。その後、実験で足したoverflowも外して元の例へ戻します。

外へ出すことが必要なデザインなら、切り抜く範囲と案内の置き場所を再設計します。画像を切り抜くためのoverflowを、理由を調べずに親から一括削除する修正は選びません。

数字を変える前に、直す範囲を決める

今回の二段階の例で、すべての重なりの原因を扱ったわけではありません。transform、opacityが1未満の場合など、位置指定とz-index以外にもまとまりを作る条件があります。既存サイトでは、子から祖先へたどり、該当する条件を資料と照合します。

また、背景の操作を止めて閉じた後に元へ戻すモーダルは、前面へ描くだけでは完成しません。dialogの開閉とフォーカス復帰のように、必要な操作も含めて設計します。今回の大きな数字を、モーダルの代用品として貼り付けないでください。

通常の本文やカードが意図せず重なっているなら、重なり順を調整する前に配置そのものを見直します。文字を読めるようにする目的で、下の文字を別の箱で覆ってしまっては解決になりません。必要な重なりと、レイアウトの不具合を分けて扱います。

四つの状態を、同じ場所で確かめる

15〜20分を目安に、保存したHTMLで次を順に試します。前の実験の変更を残さず、表の条件に合わせてから判定してください。

条件 重なった部分の期待結果
親1・子999・隣2 青い隣の箱が前にある
親1・子9999・隣2 青い隣の箱が前のまま
親3・子999・隣2 オレンジの案内が前へ出る
親3・rightを16px・stageにoverflow:hidden 案内が前にあり、右端も枠内へ収まる

広い画面と320px幅で同じ比較を行い、ページ全体が横へはみ出していないかも見ます。レスポンシブCSSの無料レッスンで別の配置を作るときは、親の数字を上げる理由と、影響する子の範囲を一緒に記録してください。

TRY A LESSON

記事の内容を、課題で確かめる

レスポンシブCSSの練習 →

CSSの学習内容 →

記事についてのお問い合わせ

記載内容へのご質問や訂正のご連絡は、hello@junkbranding.comまでお願いします。

← 記事一覧に戻る