>_devtools-hub
CSSデバッグフロントエンド

CSSが効かないときの切り分け手順 — セレクター・詳細度・レイヤー・重なり順

書いたCSSが反映されないときに、原因を上流から順番に潰していく手順をまとめます。セレクターが当たっているか、詳細度で負けていないか、@layerの順で決まっていないか、重なり順の親子関係に閉じ込められていないかを、1つずつ確かめます。

CSSが効かないとき、とりあえず !important を足したり、セレクターを長くしたりして様子を見てしまうことがあります。動くこともありますが、なぜ動いたのかが分からないまま進むので、同じ問題が別の場所で繰り返されます。原因は大きく4つに分かれ、しかも調べる順番が決まっています。セレクターが当たっていないのか、当たっているが上書きされているのか、レイヤーで先に決着がついているのか、そもそも重なり順の外に出られないのか。上流から順に潰していけば、どこで止まっているかは必ず特定できます。この記事ではその順番を紹介します。

1. まずセレクターが当たっているかを確かめる

いちばん多い原因が、そもそもそのセレクターがどの要素にも当たっていない、というものです。クラス名のタイプミス、結合子の向き違い、擬似クラスの条件が成立していない、といった単純な理由がほとんどで、スタイルの優先度を疑う前にここを潰します。開発者ツールの要素パネルでその要素に該当ルールが出ているかを見るのが基本ですが、HTMLの構造ごと切り出して試したいときは CSS Selector Tester が早いです。HTMLとセレクターを左右に貼り付けると、マッチした要素がプレビュー内で枠線付きでハイライトされ、マッチ件数も表示されます。件数が0なら、優先度の話に進む必要はありません。セレクターの書き方だけの問題です。ここで「意図した要素だけに当たっているか」も同時に確認しておくと、後で別の要素に副作用が出る事故も防げます。

この手順で使うツール

CSS Selector Tester

HTMLとCSSセレクターを入力してマッチした要素をリアルタイムハイライト

2. 当たっているのに上書きされるなら詳細度を数える

セレクターは当たっているのに値が別のルールに負けている場合は、詳細度を比べます。詳細度はIDの数、クラスや属性や擬似クラスの数、要素や擬似要素の数の3つの数値で表され、上位の数が多いほうが強く、同点なら後に書かれたほうが勝ちます。ここで誤解しやすいのが、セレクターの長さは関係がないという点です。要素セレクターをいくら並べても、クラス1つには勝てません。CSS Specificity Calculator にセレクターを入力すると内訳が3つの数値で表示され、複数本を並べて強い順に並び替えられるので、どれが勝っているかを目で確認できます。覚えておくと役立つのが :where() で、この中に書いたセレクターは詳細度に加算されません。上書きされる前提の土台のスタイルを書くときに使うと、後からの調整が楽になります。

この手順で使うツール

CSS Specificity Calculator

CSSセレクターの詳細度を (a,b,c) で即時計算・複数比較

3. @layer を使っているなら、詳細度より先にレイヤーで決まる

プロジェクトで @layer を使っている場合、判定の順番が変わります。まずレイヤーの順序で勝敗が決まり、詳細度を比べるのは同じレイヤーの中だけです。つまり後ろのレイヤーに書かれたクラス1つのルールが、前のレイヤーに書かれたID付きのルールに勝ちます。詳細度を上げても効かない、という状況はたいていこれです。もう1つ押さえておきたいのが、どのレイヤーにも属さないスタイルの扱いで、これはすべてのレイヤーより強く扱われます。リセットCSSやライブラリをレイヤーに入れ、自分のスタイルはレイヤー外に置く、という構成が使われるのはこのためです。いま使っているレイヤー名を CSS @layer Visualizer に同じ順で並べてみると、どの順で評価されるかが優先度のバーとして見えるので、負けている側がどこにいるかを目で確かめられます。なお !important が付いた場合はレイヤーの強弱が反転するので、importantを混ぜると読みづらくなる点にも注意してください。

この手順で使うツール

CSS @layer Visualizer

カスケードレイヤーの優先度をビジュアル表示・ドラッグ並び替えで@layer CSS即生成

4. 前面に出ないのは z-index ではなく重なり順の親子関係

z-index を大きくしても要素が前に出てこない、という詰まり方があります。これは数値の問題ではなく、その要素がどのスタッキングコンテキストに属しているかの問題です。ある要素がスタッキングコンテキストを作ると、その子孫の z-index はその内側でしか効かなくなり、どれだけ大きな値を入れても親より前には出られません。スタッキングコンテキストを作る条件は z-index 付きの position だけではなく、opacity が1未満、transform や filter の指定、will-change、isolation: isolate なども該当します。見た目をわずかに調整するつもりで付けた opacity が原因になっていることも珍しくありません。CSS Stacking Inspector にCSSを貼り付けると、どの要素がスタッキングコンテキストを作っているかがツリーで表示されるので、閉じ込めている親を特定できます。直すときは z-index を上げるのではなく、その親を取り除くか、要素自体をコンテキストの外へ出します。

この手順で使うツール

CSS Stacking Inspector

z-index とスタッキングコンテキストをツリーで可視化

5. 適用されているのに幅や位置がずれる

開発者ツールでルールが適用されていると表示されているのに、思った見た目にならないこともあります。このときはまずボックスの計算方法を疑います。よくあるのが box-sizing の取り違えで、content-box では width に padding と border が加算されるため、指定した幅と実際に占める幅がずれます。横に3つ並べたカードが1つだけ折り返す、といった崩れ方の多くはこれです。CSS Box Model Visualizer で margin、padding、border を個別に動かすと、同心の四角形として内訳が見えるので、どこが幅を食っているのかを数字と図で把握できます。box-sizing を content-box と border-box で切り替えたときに、同じ指定でも占有幅が変わることもその場で確認できます。幅の計算が合っていないときは、セレクターや優先度をいくら見直しても解決しません。

この手順で使うツール

CSS Box Model Visualizer

margin / padding / border を色分けビジュアルで確認しながら CSS 生成

6. 値そのものが届いていないとき

計算方法も正しいのに効かない場合、最後に疑うのが値です。カスタムプロパティを使っていると、変数名のタイプミスや、その要素まで変数が継承されていない場合に、宣言だけが残って無効になります。開発者ツールでは宣言が表示されるため、一見すると適用されているように見えるのがやっかいなところです。CSS Variable Inspector にCSSを貼り付けると、定義されている変数がセレクター単位でまとめて抽出されるので、どのスコープで何が定義されているかを一覧で確認できます。色はカラーピッカー、数値はスライダーで値を変えられるため、その変数が本当に見た目へ効いているかも試せます。変数を参照する側には初期値を添えておくと、届かなかったときに無効になるのではなく初期値へ落ちるので、こうした問題は起きにくくなります。

この手順で使うツール

CSS Variable Inspector

CSSカスタムプロパティを抽出・カラーピッカー/スライダーでリアルタイム編集

まとめ

CSSが効かないときは「セレクターが当たっているか → 詳細度で負けていないか → レイヤーで先に決まっていないか → 重なり順に閉じ込められていないか → 幅の計算は合っているか → 値は届いているか」の順で見ると、当て推量なしで原因にたどり着けます。特に「セレクターの長さは詳細度と無関係」「@layerでは詳細度より先にレイヤー順で決まる」「opacityやtransformもスタッキングコンテキストを作る」の3点は、知っているかどうかで調査時間が大きく変わります。

このツールで試す

CSS Specificity Calculator

CSSセレクターの詳細度を (a,b,c) で即時計算・複数比較

CSS開発者向け

使ってみる →

BOOTH

CSS Variable Inspector

CSSカスタムプロパティを抽出・カラーピッカー/スライダーでリアルタイム編集

CSS開発者向け

使ってみる →

BOOTH

CSS Stacking Inspector

z-index とスタッキングコンテキストをツリーで可視化

CSS開発者向け

使ってみる →

BOOTH

CSS Box Model Visualizer

margin / padding / border を色分けビジュアルで確認しながら CSS 生成

CSSデザイン開発者向け

使ってみる →

BOOTH

CSS @layer Visualizer

カスケードレイヤーの優先度をビジュアル表示・ドラッグ並び替えで@layer CSS即生成

CSS開発者向け

使ってみる →

BOOTH

CSS Selector Tester

HTMLとCSSセレクターを入力してマッチした要素をリアルタイムハイライト

CSS開発者向けWeb開発

使ってみる →

BOOTH

関連ガイド