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を一度に直すのではなく、比較する二要素を固定します。
- 前へ出したい要素の
positionを確認します。staticなら、z-indexの数値ではなく、まず位置指定が必要かを判断します。 - 両方の要素から祖先をたどります。
positionがstatic以外で、整数のz-indexを持つ祖先を記録します。 - 二要素が直接比較される共通のstacking contextを見つけます。子自身の数値ではなく、そのcontext内にある親側のstack levelを比べます。
- ページ上の目的を決めます。親のまとまり全体を前へ出すのか、特定の子だけを別のまとまりより前へ出すのかを分けます。
- 目的に関係する最も近い要素だけを変更し、二要素の前後関係を確認します。
配置する座標と描画する前後関係は別の問題です。topやleftの基準が違うなら包含ブロックを調べ、前後が違うならstacking contextを調べます。z-indexの数値を増やし続ける前に、どちらを直す作業なのかを分けてください。
関連記事

