CSSのスタイルが効かない場合、ほとんどの原因は優先度の問題です。この記事で優先度のルールを明確に説明します。
優先度の重み
| セレクターの種類 | 重み | 例 |
|---|---|---|
| !important | 最高(すべてを上書き) | color: red !important |
| インラインスタイル | 1000 | style="color: red" |
| IDセレクター | 100 | #header |
| クラス/属性/擬似クラス | 10 | .active, [type="text"], :hover |
| 要素/擬似要素 | 1 | div, p, ::before |
| ユニバーサルセレクター | 0 | * |
計算方法
重みは3桁の数値を別々にカウントします(10進数として足し算するのではありません):
フォーマット:(インライン, ID, クラス/属性/擬似クラス, 要素)
a { color: red } → (0, 0, 0, 1)
.nav a { color: red } → (0, 0, 1, 1)
#header .nav a { color: red } → (0, 1, 1, 1)
比較は上位の桁から始め、大きい方が優先します:
css
/* どちらが適用される? */
#header a {
color: blue;
} /* (0, 1, 0, 1) */
.nav .link a {
color: red;
} /* (0, 0, 2, 1) */
/* 結果:#header a が適用 — IDの桁 1 > 0 */
同じ優先度:後に書いた方が上書き
css
.btn {
color: red;
}
.btn {
color: blue;
} /* 後に書いた方が適用 — ボタンは青色 */
実際のシナリオ
css
/* シナリオ:コンポーネントライブラリのスタイルを上書きする */
/* Element UIのボタン */
.el-button {
color: #409eff;
}
/* あなたの上書き */
.el-button {
color: red;
} /* 効かない — ライブラリのCSSがあなたの後に読み込まれる可能性 */
/* 強制上書き(非推奨だが、やむを得ない場合もある)*/
.el-button {
color: red !important;
}
/* より良い方法:詳細度を上げる */
.my-page .el-button {
color: red;
} /* 親セレクターを追加して重みを上げる */
!important の使用原則
css
/* ❌ !importantの悪循環 */
.btn {
color: red !important;
}
.special-btn {
color: blue !important;
}
/* 両方!importantになると、また後書き優先の問題に戻る */
/* ✅ !importantの正当な用途 */
/* ユーティリティクラス:明示的に強制上書きするため */
.text-center {
text-align: center !important;
}
.hidden {
display: none !important;
}
よくある誤解
css
/* 誤解:ネストが深いほど重みが高い */
div div div div {
color: red;
} /* (0, 0, 0, 4) */
.active {
color: blue;
} /* (0, 0, 1, 0) */
/* 結果:.active が適用 — クラスセレクター > 要素セレクター */
/* 誤解:擬似要素::beforeと擬似クラス:hoverの重み */
a::before {
} /* 重み1(擬似要素) */
a:hover {
} /* 重み10(擬似クラス) */
開発上のアドバイス
1. !importantは安易に使わない — メンテナンスが困難になる
2. BEM命名を使ってネストの深さを減らし、優先度の衝突を減らす
3. スタイルが効かない場合はDevToolsでどのルールが上書きされているか確認
4. コンポーネントライブラリのスタイル上書きは!importantより親セレクターの追加で対応
まとめ
- 重みの高い順:!important > インライン > ID(100) > クラス/属性/擬似クラス(10) > 要素(1)
- 同じ重み:後に書いた方が上書き
- 重みの比較は桁ごとの比較であり、単純な足し算ではない
!importantはなるべく使わず、詳細度を上げて対応する