「z-index: 100;」を指定したのに要素が前面に出ません。一番に疑うべき原因はどれ?
解説
正解は「positionプロパティが初期値のまま」です。CSSの z-index プロパティは、要素の重なり順を制御するためのものですが、「position プロパティが static(初期値)以外の要素にしか効かない」という絶対的なルールがあります。そのため、どれだけ z-index: 9999; と大きな数値を指定しても、position の指定が漏れていると全く機能しません。他の選択肢である display の値や !important の有無は、重なり順の基本的な仕組みとは直接関係ありません。position と z-index の切っても切れない関係HTMLの要素は、デフォルトでは上から下へと順番に配置されていきます(この状態が position: static; です)。この平らな紙のような状態では、要素が「重なる」という概念自体が存在しません。要素を重ねるためには、要素を紙からフワッと浮かせたような状態にする必要があります。これを行うのが position プロパティです。具体的には、以下のいずれかの値を指定したときに初めて z-index が有効になります。position: relative; (元の位置を基準に配置)position: absolute; (親要素を基準に絶対配置)position: fixed; (画面を基準に固定配置)position: sticky; (スクロールに応じて固定)「z-indexが効かない!」と焦ったときは、まず開発者ツールを開いて、その要素に position: relative; などが当たっているかを確認するのがデバッグの第一歩です。「z-index: 9999」でも最前面に出ない!スタッキングコンテキストの罠position を正しく指定しているのに、それでも z-index が効かない(他の要素の下に潜ってしまう)ケースがあります。これが中級者以上でもよくハマる「スタッキングコンテキスト(階層構造)」の罠です。z-index の数値は、Webページ全体で共通の絶対的なランキングではありません。「同じ親要素を持つ兄弟要素の中でのランキング」に過ぎないのです。<div class='parent-A' style='position: relative; z-index: 1;'> <div class='child-A' style='position: relative; z-index: 9999;'>子要素A</div> </div> <div class='parent-B' style='position: relative; z-index: 2;'> <div class='child-B' style='position: relative; z-index: 1;'>子要素B</div> </div>上記の例では、子要素Aは z-index: 9999 を持っていますが、子要素B(z-index: 1)の下に隠れてしまいます。なぜなら、親同士の勝負で「親A (z-index: 1) < 親B (z-index: 2)」と負けてしまっているからです。親が負けている以上、子供がどれだけ頑張っても勝つことはできません。この場合は、親要素の z-index を見直す必要があります。プロが現場でどう判断しているか実務の現場では、場当たり的に z-index: 9999; や z-index: 10000; のような極端な数値を指定することは「アンチパターン(避けるべき悪い書き方)」とされています。これをやってしまうと、後から別のモーダルやヘッダーを追加した際に「9999より上にしたいから99999にする」という終わりのない軍拡競争が始まってしまうからです。保守性の高いCSSを書くプロジェクトでは、以下のような工夫がされています。z-index: 10;、20;、30; のように、間に他の要素を差し込めるよう余裕を持った数値を設定する。CSS変数(カスタムプロパティ)やSassの変数を使って、--z-index-modal: 100;、--z-index-header: 50; のように一元管理する。不要な z-index は指定せず、HTMLの記述順(後に書いたものほど上に重なる)というデフォルトの挙動を活かす。「なぜ重ならないのか」という仕組みを理解することで、力技に頼らないスマートなCSS設計ができるようになります。