詳細度とカスケード完全理解 — CSSが効かない原因の9割はここにある
この章の目次開く
「スタイルを書いたのに当たらない」「なぜか別のスタイルが優先される」——CSSでぶつかるトラブルの大半は、詳細度(Specificity)かカスケードが原因です。逆に、この2つを理解すれば「CSSが効かない」問題はほとんど自力で解決できるようになります。
学習者スタイルを書いたのに効かない…!結局 !important を付けて無理やり通しちゃうんだけど、これでいいの?
!important は一時しのぎにはなりますが、後から更に困ることになります。まず「なぜ効かないのか」を理解する仕組みから見ていきましょう。

カスケードとは — スタイルの優先順位を決めるルール
同じ要素に複数のスタイルが当たるとき、どれが勝つかを決める仕組みがカスケード(Cascade)です。CSSの「C」はまさにこれです。
優先順位は上から順に判定されます。
| 判定順 | ルール | 具体例 |
|---|---|---|
| 1. Origin | !important > 作者のCSS > ブラウザのデフォルト | !important が付いたスタイルは最優先 |
| 2. 詳細度 | より具体的なセレクタが勝つ | #title は .title に勝つ |
| 3. 記述順 | 同じ詳細度なら後に書いた方が勝つ | 同じ .btn の定義が2箇所あれば後者が適用 |
ほとんどの「効かない」トラブルは 2. 詳細度 が原因です。
詳細度の計算 — (A, B, C) の3桁
詳細度は (A, B, C) の3つの数値で表されます。左の桁ほど重みが大きく、左から順に比較して大きい方が勝ちます。
| セレクタの種類 | 加算される桁 | 例 |
|---|---|---|
インラインスタイル(style="") | A に +1 → (1,0,0) | <p style="color:red"> |
| IDセレクタ | A に +1 → (1,0,0) | #title |
| クラス・属性・擬似クラス | B に +1 | .card, [type="text"], :hover |
| タイプ(要素)・擬似要素 | C に +1 | div, p, ::before |
ユニバーサル(*)、結合子(>, +) | 加算なし (0,0,0) | *, .card > p の > |
計算例
p /* (0,0,1) — タイプ1つ */
.text /* (0,1,0) — クラス1つ */
p.text /* (0,1,1) — タイプ1 + クラス1 */
#title /* (1,0,0) — ID1つ */
.card p /* (0,1,1) — クラス1 + タイプ1 */
.nav .item:hover /* (0,3,0) — クラス2 + 擬似クラス1 */
#header .nav a /* (1,1,1) — ID1 + クラス1 + タイプ1 */
div#content .text p /* (1,1,2) — ID1 + クラス1 + タイプ2 */
学習者(0,3,0) って (0,1,2) より強いの?B桁が3 vs 1だから、C桁がいくつあっても勝てないってこと?
先生そのとおり!左の桁が1でも大きければ、右の桁がどんなに積み上がっても逆転できない。クラス100個並べても、ID1つに勝てないんだ。
実際の競合を読み解く
クラス vs タイプセレクタの組み合わせ
nav a { color: red; } /* (0,0,2) — タイプ2つ */
.link { color: blue; } /* (0,1,0) — クラス1つ → こちらが勝つ */タイプセレクタは C の桁に加算されるだけなので、クラス1つ(B に+1)に勝てません。
IDセレクタが強すぎる問題
#content { font-size: 14px; } /* (1,0,0) */
.content { font-size: 16px; } /* (0,1,0) — 負ける */IDセレクタを使うと詳細度が跳ね上がり、クラスで上書きできなくなります。
同じ詳細度 → 後に書いた方が勝つ
.btn { background: blue; } /* (0,1,0) */
.btn { background: green; } /* (0,1,0) — 同じ詳細度 → 後者が勝つ */CSSファイルの読み込み順や、<link> タグの順番でも同じ原理が働きます。複数のCSSファイルを読み込むとき、後に読んだファイルのスタイルが優先されます。
!important — 最終手段であり、ほぼ使うべきでない
p { color: red !important; }
p { color: blue; } /* これは負ける */!important はOriginの段階で通常のスタイルに勝つため、詳細度を無視して強制適用されます。

問題は !important を上書きするには !important が必要なことです。
/* !importantの連鎖 — 絶対にやってはいけない */
.text { color: red !important; }
.text.highlight { color: blue !important; } /* さらにimportant */
#main .text { color: green !important; } /* さらにimportant + ID */
先生!important を使いたくなったら、それは「詳細度の設計が壊れている」というサインだよ。セレクタを見直す方が正しい解決策なんだ。
!important が許容されるケース
- サードパーティCSSの上書き:外部ライブラリのスタイルをどうしても変えたいとき
- ユーティリティクラス:Tailwind CSSのような「最終的に勝つべきクラス」の定義
これ以外では基本的に使わないでください。
継承(Inheritance)
一部のプロパティは親要素から子要素に自動で引き継がれます。これを継承と呼びます。
body {
font-family: sans-serif;
color: #1a1a2e;
line-height: 1.7;
}
/* ↑ すべての子孫要素にも適用される */継承されるプロパティ・されないプロパティ
| 継承される | 継承されない |
|---|---|
color | margin |
font-family, font-size | padding |
line-height | border |
text-align | background |
cursor | width, height |
visibility | display |
覚え方:テキストに関するプロパティは継承される、ボックスに関するプロパティは継承されない。
継承を明示的に操作する
.child {
border: inherit; /* 通常継承されないborderを強制的に継承 */
color: initial; /* 継承を無視してブラウザのデフォルト値に戻す */
all: unset; /* すべてのプロパティを初期化 */
}DevToolsでの詳細度確認
「なぜこのスタイルが当たらないのか」をDevToolsで確認する方法を知っておくと、デバッグが格段に速くなります。
- 要素を右クリック →「検証」でDevToolsを開く
- Styles パネルで、適用されているスタイルが上から優先順に表示される
- 打ち消し線が引かれているプロパティは、より詳細度の高いスタイルに負けている
- セレクタにカーソルを合わせると、詳細度
(A, B, C)が表示される(Chrome)
詳細度を低く保つ設計指針
プロジェクトが大きくなるほど、詳細度の管理が重要になります。
やるべきこと
- クラスセレクタ中心で書く(
(0,1,0)同士なら記述順で制御できる) - セレクタは短く保つ(
.card-title>.card .content .title) - BEM記法(
.block__element--modifier)でネストを浅くする
避けるべきこと
- IDセレクタでスタイルを当てる
- タイプセレクタの深いネスト(
main section article p span) !importantで無理やり通す- インラインスタイル(
style="")を多用する
/* ❌ 詳細度が高すぎる */
#sidebar .nav ul li a.active { color: blue; } /* (1,2,3) */
/* ⭕ クラス1つで十分 */
.nav-link--active { color: blue; } /* (0,1,0) */よくあるハマりどころ
リセットCSSとの競合
ブラウザのデフォルトスタイルを打ち消す「リセットCSS」は、タイプセレクタ (0,0,1) で書かれていることが多いです。クラスセレクタ (0,1,0) で書いていれば負けないので問題になりませんが、タイプセレクタ同士で書いていると記述順の勝負になり混乱します。
CSSファイルの読み込み順
<link rel="stylesheet" href="base.css">
<link rel="stylesheet" href="components.css">
<!-- components.css の方が後なので、同じ詳細度なら勝つ -->読み込み順が意図と違うと、「書いたはずのスタイルが効かない」ことがあります。
ちゃんと使うためのポイント
- セレクタはなるべく詳細度を低く保つ(クラス中心、IDや深いネストは避ける)
!importantは使わない。使いたくなったらセレクタの設計を見直すサイン- 「スタイルが当たらない」ときはDevToolsのStylesパネルで打ち消し線と詳細度を確認する
- テキスト系プロパティは継承される、ボックス系は継承されないと覚える
- CSSファイルの読み込み順も優先順位に影響する
次の最終章では、実務で頻繁に使うCSSの実践パターン集をまとめます。
参考リンク
- MDN — 詳細度 — 詳細度の計算ルールの公式解説
- MDN — カスケード入門 — カスケード(Origin・優先順位)の公式解説
- MDN — 継承 — 継承の仕組みの公式解説
- MDN — !important —
!importantの挙動と注意点
