詳細度とカスケード — スタイルが当たらない理由を理解する
「スタイルを書いたのに当たらない」「なぜか別のスタイルが優先される」——CSSあるあるの原因は、ほぼ詳細度(Specificity)かカスケードにあります。
学習者スタイルを書いたのに効かない…!結局 !important を付けて無理やり通しちゃうんだけど、これでいいの?

カスケードとは
同じ要素に複数のスタイルが当たるとき、どれが優先されるかを決めるルールです。優先順位は次の順番で決まります。
- Origin(スタイルの出所)
- ブラウザのデフォルト < 作者のスタイル <
!important
- ブラウザのデフォルト < 作者のスタイル <
- 詳細度(Specificity)
- より具体的なセレクタが勝つ
- 記述順
- 同じ詳細度なら後に書いたものが勝つ
詳細度の計算
詳細度は (a, b, c) の3つの数値で表されます。
| セレクタの種類 | 加算 |
|---|---|
インラインスタイル(style="") | (1,0,0) |
IDセレクタ(#id) | (0,1,0) |
クラス・属性・擬似クラス(.class, [attr], :hover) | (0,0,1) |
タイプ・擬似要素(div, ::before) | (0,0,1) |
ユニバーサル(*) | (0,0,0) |
p /* (0,0,1) */
.text /* (0,1,0) */
#title /* (1,0,0) */
.card p /* (0,1,1) */
.nav .item:hover /* (0,2,1) */
#header .nav a /* (1,1,1) */左から順に比較して、大きいものが勝ちます。
!important
p { color: red !important; }
p { color: blue; } /* これは負ける */!important は詳細度の計算を無視して強制的に適用します。しかし乱用すると後から上書きできなくなり、メンテナンスが困難になります。基本的に使わないことが推奨されます。
継承(Inheritance)
一部のプロパティは親要素から子要素に継承されます。
body {
font-family: sans-serif;
color: #1a1a2e;
line-height: 1.7;
}
/* すべての子孫要素に適用される */継承されるプロパティ(代表): color, font-*, line-height, text-align など
継承されないプロパティ(代表): margin, padding, border, background, width, height など
inherit を明示的に書くと、継承されないプロパティも強制的に継承できます。
.child {
border: inherit; /* 親のborderを継承 */
}よくあるハマりどころ
クラスなのに当たらない
nav a { color: red; } /* (0,0,2) */
.link { color: blue; } /* (0,1,0) — こちらが勝つ */.link の方が詳細度が高いので color: blue が適用されます。
IDセレクタが強すぎる
#content { font-size: 14px; } /* (1,0,0) */
.content { font-size: 16px; } /* (0,1,0) — 負ける */IDセレクタを使うと詳細度が跳ね上がり、クラスで上書きできなくなります。
ちゃんと使うためのポイント
- セレクタはなるべく詳細度を低く保つ(クラス中心、IDや要素セレクタの深いネストは避ける)
!importantは使わない。どうしても使いたくなったらセレクタの詳細度設計を見直す- 「スタイルが当たらない」ときはデベロッパーツールで詳細度を確認する
次の最終章では、実務で頻繁に使うCSSの実践パターン集をまとめます。