• z-indexが効かないときはpositionとstacking contextの境界を確認する

z-indexが効かないときはpositionとstacking contextの境界を確認する

公開日: 執筆:佐藤

z-indexの数値を大きくしても要素が前面へ出ないときは、数値そのものより、二つの条件を先に確認します。対象がposition: staticのままではないか。比較する二つの要素が、同じstacking contextに属しているか。この二点です。

z-indexは、同じstacking context内にある位置指定要素の重なり順を決めます。子要素へz-index: 9999を指定しても、その親が低い重なり順のstacking contextを作っていれば、子だけを別のstacking contextより前へ出すことはできません。対象要素から祖先をたどり、どの要素がstacking contextを作っているかを確認してから直します。

z-indexはpositionがstatic以外の要素へ適用する

CSS 2.1のz-indexの定義では、z-indexは位置指定された要素へ適用します。位置指定された要素とは、positionの計算値がstatic以外である要素です。

次のHTMLとCSSは、指定の違いを示すための仮例です。

<div class="notice">重要なお知らせ</div>
<div class="header">ヘッダー</div>
.notice {
  z-index: 10;
}

positionの初期値はstaticです。このままでは、CSS 2.1の規則において.noticeへz-indexは適用されません。まず、配置の目的に合うpositionを指定します。

.notice {
  position: relative;
  z-index: 10;
}

ただし、position: relativeを加えれば、すべての重なりが直るわけではありません。次に、前後を比較したい要素が同じstacking contextにいるかを確認する必要があります。

整数のz-indexは重なり順とstacking contextを同時に作る

位置指定要素へ整数のz-indexを指定すると、その整数は現在のstacking context内におけるstack levelになります。同時に、その要素は新しいstacking contextを作ります。

z-index: autoでは、現在のstacking context内のstack levelは0です。ルート要素を除き、新しいstacking contextは作りません。整数の0を指定した場合は、同じstack level 0でも新しいstacking contextを作ります。autoと0は、この点が異なります。

同じstacking context内では、大きいstack levelの要素が小さいものより前へ描画されます。同じstack levelなら、文書ツリーで後にある要素が前へ描画されます。したがって、比較する相手とcontextが同じなら、z-indexの大小を確認します。contextが異なるなら、子の数値を比べても原因は分かりません。

子のz-indexは親のstacking contextから外へ出られない

次の例も、重なりの関係を説明するための仮例です。

<div class="panel panel-a">
  <div class="dialog">設定画面</div>
</div>
<div class="panel panel-b">別のパネル</div>
.panel-a {
  position: relative;
  z-index: 1;
}

.panel-b {
  position: relative;
  z-index: 2;
}

.dialog {
  position: absolute;
  z-index: 9999;
}

.panel-aと.panel-bは、共通の親側のstacking contextで比較されます。.panel-aのstack levelは1、.panel-bは2なので、.panel-bが前です。

.dialogのz-index: 9999は、.panel-aが作ったstacking contextの中でだけ働きます。親から見たstacking contextは一つの単位として扱われ、別のcontextに属する箱を、その内部の箱の間へ差し込むことはできません。したがって、.dialogの数値をさらに大きくしても、.panel-bより前には出ません。

.panel-a全体を前へ出す必要があるなら、共通のcontextで比較される親側のstack levelを直します。たとえば、ほかの配置条件を確認したうえで、.panel-aを3へ変更します。

.panel-a {
  position: relative;
  z-index: 3;
}

一方、.panel-aは後ろへ残し、.dialogだけを.panel-bより前へ出したいなら、数値の変更だけでは目的を満たしません。.dialogを、.panel-bと比較できるstacking contextへ置くようにHTMLとCSSの役割を見直します。親のz-indexを削除する方法もありますが、その親がcontextを作る理由を確認せずに削除すると、別の重なりを変えてしまいます。

painting orderはstacking contextごとに適用される

CSS 2.1のpainting orderは、各stacking contextの背景と枠、負のstack levelを持つ子context、通常フローの内容、stack level 0の位置指定要素、正のstack levelを持つ子contextなどを、定められた順序で描画します。この順序は、子のstacking contextにも繰り返し適用されます。

そのため、画面上で重なっている二要素のz-indexだけを見ても、描画順は判断できません。各要素がどのstacking contextに属し、そのcontext自体が親のcontextでどの位置にあるかをたどります。

負の整数もz-indexの値として使えます。ただし、負の値を指定した要素は、同じcontext内の通常の内容より後ろへ回ることがあります。「前へ出ないから負の値を試す」という調整では、原因の切り分けになりません。

z-indexが効かない原因は二要素から順に調べる

最初に、前へ出したい要素と、その前を覆っている要素を一つずつ選びます。ページ全体のz-indexを一度に直すのではなく、比較する二要素を固定します。

  1. 前へ出したい要素のpositionを確認します。staticなら、z-indexの数値ではなく、まず位置指定が必要かを判断します。
  2. 両方の要素から祖先をたどります。positionがstatic以外で、整数のz-indexを持つ祖先を記録します。
  3. 二要素が直接比較される共通のstacking contextを見つけます。子自身の数値ではなく、そのcontext内にある親側のstack levelを比べます。
  4. ページ上の目的を決めます。親のまとまり全体を前へ出すのか、特定の子だけを別のまとまりより前へ出すのかを分けます。
  5. 目的に関係する最も近い要素だけを変更し、二要素の前後関係を確認します。

配置する座標と描画する前後関係は別の問題です。topやleftの基準が違うなら包含ブロックを調べ、前後が違うならstacking contextを調べます。z-indexの数値を増やし続ける前に、どちらを直す作業なのかを分けてください。

戻る