カスケード(Cascade)とは?
カスケードとは、ブラウザが要素にどのスタイルを適用するかを決める 優先順位付けのプロセス全体 のことです。
身近な例で考えてみましょう。学校で複数の先生から指示を受けた時のことを想像してください:
- 校長先生:「全校生徒は制服を着用してください」
- 担任の先生:「我がクラスは体操服で活動します」
- 体育の先生:「田中くん、今日は特別にジャージでOKです」
この場合、田中くんはどの指示に従うでしょうか?より 具体的で直接的な指示 ほど優先されますよね。
CSSでも同じように、ブラウザは 4つのステップ を順番にチェックして、最終的にどのスタイルを適用するかを決定します。
なぜこのような複雑な仕組みが必要なのでしょうか?
- 複数のCSSファイル 一つのWebページに複数のCSSファイルが読み込まれることがある
- ライブラリとの競合 BootstrapなどのCSSライブラリと独自CSSが混在する
- チーム開発 複数の開発者が同じプロジェクトでCSSを書く
- 継承との組み合わせ 親要素から継承されたスタイルと直接指定されたスタイルが競合する
カスケードがあることで、これらの複雑な状況でも 一貫した方法 でスタイルが決定され、開発者は予測可能な結果を得ることができます。
カスケードの判定基準
CSSカスケードでは、上位の基準で決着がつけば、下位の基準は無視されるという重要なルールがあります。
判定の優先順序
- スタイルの起源 誰が書いたCSSかをチェック(ブラウザ、ユーザー、開発者)
- 重要度
!importantが付いているかをチェック - 詳細度 セレクターがどれだけ具体的かをチェック
- 出現順 同じ詳細度なら後に書かれたものが勝利
判定プロセスの例
4つのステップがどのように働くか、具体的な例で見てみましょう:
/* スタイルA: ブラウザ標準 */
p { color: black; }
/* スタイルB: 開発者CSS(外部ファイル) */
p { color: blue; }
/* スタイルC: 開発者CSS(同じファイル内、後に記述) */
p { color: green; }
/* スタイルD: インラインスタイル */
<p style="color: red;">この段落は何色?</p> 判定の流れ
- 起源チェック ブラウザ標準(A)< 開発者CSS(B,C,D)→ B,C,Dが残る
- 重要度チェック
!importantなし → 全て同じ重要度でB,C,Dが残る - 詳細度チェック インライン(D)> 要素セレクター(B,C)→ Dが勝利
- 出現順チェック Dで決定済みなので、この段階はスキップ
結果: この段落は赤色で表示されます。
スタイルの起源判定
スタイルの起源とは、そのCSSルールが どこから来たのか を表す分類です。ブラウザは起源によって基本的な優先順位を決めています。
3つの起源と優先順位
CSSには以下の3つの起源があり、下に行くほど優先度が高くなります:
ブラウザ標準スタイル(User Agent Stylesheet)
ブラウザ標準スタイルは、ブラウザが自動的に適用する基本的なスタイルです。
- 見出しタグ
h1〜h6の文字サイズとmargin - リンク
<a>タグの青色とアンダーライン - リスト
<ul>、<ol>の箇条書きマーカー - フォーム ボタンや入力欄の基本デザイン
例:ブラウザ標準で適用されるスタイル
/* ブラウザが自動的に適用している基本スタイル(例) */
h1 {
font-size: 2em;
margin: 0.67em 0;
font-weight: bold;
}
a {
color: blue;
text-decoration: underline;
}
p {
margin: 1em 0;
} これらのスタイルがあるおかげで、CSSを何も書かなくても見出しが大きく表示され、リンクが青色になるのです。
ユーザー設定スタイル(User Stylesheet)
ユーザー設定スタイルは、Webサイトを閲覧するユーザーが設定したスタイルです。
- ブラウザの拡張機能 ダークモード、フォントサイズ変更
- アクセシビリティ設定 高コントラスト、大文字化
- ブラウザ設定 デフォルトフォント、ズームレベル
- カスタムCSS 上級ユーザーが設定した独自スタイル
開発者スタイル(Author Stylesheet)
開発者スタイルは、私たちWeb開発者が作成するスタイルで、最も優先度が高い起源です。
開発者スタイルには、さらに詳細な分類があります:
- 外部CSSファイル
<link>タグで読み込むスタイル - 内部CSS
<style>タグ内に記述するスタイル - インラインスタイル
style属性に直接書くスタイル
<!-- 外部CSSファイル -->
<link rel="stylesheet" href="style.css">
<!-- 内部CSS -->
<style>
.button { background: blue; }
</style>
<!-- インラインスタイル -->
<button style="background: red;">ボタン</button> 起源判定の実例
同じ要素に複数の起源からスタイルが適用されている例を見てみましょう:
/* ブラウザ標準スタイル(自動適用)
h1 {
font-size: 2rem;
font-weight: bold;
...
}
*/
/* 開発者CSS */
.custom-heading {
font-size: 1.5em;
color: blue;
} <h1>ブラウザ標準スタイルの見出し</h1>
<h1 class="custom-heading">開発者スタイルの見出し</h1> 2つの見出しを比較することで、起源の違いが明確に分かります:
- 1つ目の見出し ブラウザ標準スタイル(大きいサイズ、黒色)
- 2つ目の見出し 開発者スタイル(小さいサイズ、青色)が優先適用
- 起源判定の結果 ブラウザ標準 < 開発者CSS
なぜ「ブラウザ標準 < ユーザー設定 < 開発者」の順序になっているのでしょうか?
- ブラウザ標準 最低限の見た目を保証する基盤
- ユーザー設定 個人のニーズ(アクセシビリティなど)を尊重
- 開発者スタイル サイトの意図したデザインを実現
この順序により、基本的には開発者の意図したデザインが表示され、必要に応じてユーザーの設定が優先される、バランスの取れた仕組みになっています。
重要度判定(!important)
!importantの動作
!importantは、CSSプロパティ値の後に付けることで、そのスタイルを強制的に適用させるキーワードです。
/* 基本的な書き方 */
.button {
background-color: blue !important;
color: white !important;
} !importantの優先度
!importantは非常に強力で、以下のような優先順位になります:
- !important付きスタイル 最優先で適用される
- 通常のスタイル
!important無しのスタイルは全て後回し
実際の動作例
同じ要素に対して、通常のスタイルと!important付きスタイルが競合する例を見てみましょう:
通常のCSSでは「後に書かれたルールが優先される」というのが基本的なルールです。この仕組みは「出現順判定」として後の章で詳しく解説します。ここでは!importantがこの通常のルールにどう影響するかを見てみましょう。
/* 先に書かれたスタイル */
.button {
background-color: green !important; /* !important付き */
color: blue; /* 通常のスタイル */
}
/* 後に書かれたスタイル */
.button {
background-color: red; /* 通常のスタイル */
color: white; /* 通常のスタイル */
} <button class="button">どちらのスタイルが適用される?</button> 結果: background-colorは緑色(!important が勝利)、colorは白色(後に書かれた方が適用)
この例では以下の判定が行われます:
- background-color
!important付きの緑色が、後に書かれた赤色を上書きして強制適用される - color 両方とも通常のスタイルなので、後に書かれた白色が先の青色を上書きして適用される
!important同士の競合
複数の!importantが競合した場合はどうなるでしょうか?この場合は、カスケードの他のルールで判定されます:
/* 同じ要素に2つの !important スタイル */
.button {
background: yellow !important; /* 先に記述 */
}
.button {
background: purple !important; /* 後に記述(勝利) */
} この場合、後に書かれた紫色が適用されます。
!importantの使用指針
!importantは便利ですが、乱用すると管理が困難になります。適切な使い分けが重要です。
使用してもよい場面
- 外部ライブラリの上書き BootstrapなどのCSSフレームワークを部分的に変更
- ユーティリティクラス
.hidden { display: none !important; }のような汎用スタイル - 緊急対応 本番環境での一時的な修正
避けるべき使い方
- 通常開発での多用 設計を見直すべきサイン
- 詳細度問題の解決 適切なセレクターで対応すべき
- !important の重ね掛け 悪循環の原因となる
良い例と悪い例
/* 良い例:ユーティリティクラス */
.text-center { text-align: center !important; }
.hidden { display: none !important; }
/* 悪い例:設計不良の隠蔽 */
.header { color: blue !important; }
.content { margin: 20px !important; }
/* 本来はより適切な設計でセレクターの指定を変更するかCSS構造で解決すべき問題 */ 詳細度判定(Specificity)
**詳細度(Specificity)**とは、CSSセレクターがどれだけ 具体的に要素を特定しているか を表す数値です。ブラウザは詳細度が高いセレクターのスタイルを優先的に適用します。
身近な例で考えてみましょう。郵便の宛先を想像してください:
- 「日本の人へ」 → 曖昧すぎて届かない
- 「東京都の田中さんへ」 → まだ特定できない
- 「東京都渋谷区1-2-3 田中太郎さんへ」 → 確実に届く
CSSでも同じように、より 具体的なセレクター ほど「確実にその要素に届く」として優先されるのです。
詳細度の計算方法
CSSの詳細度は、4桁の数値で計算されます。左から順に重要度が高く、各桁の値を組み合わせて最終的な詳細度が決まります。
p
.button
#header .nav
style="color: red"
詳細度の点数が高いほど優先度が高くなり、ブラウザはより高い詳細度を持つセレクターのスタイルを優先的に適用します。
インラインスタイル(style属性)
インラインスタイルは、HTML要素のstyle属性に直接書かれたCSSで、最も高い詳細度(1000点)を持ちます。
<!-- インラインスタイル:詳細度 1-0-0-0 (1000点) -->
<p style="color: red; font-size: 16px;">
この段落は赤色で表示される
</p> - 詳細度 1-0-0-0(1000点)
- 特徴 HTML要素に直接結合されているため最優先
- 用途 動的スタイル変更、一時的なオーバーライド
- 注意点 HTMLとCSSが混在するため、保守性が低下
IDセレクター
IDセレクターは、要素のid属性を指定するセレクターで、高い詳細度(100点)を持ちます。
/* IDセレクター:詳細度 0-1-0-0 (100点) */
#header {
background: blue;
}
#main-content {
padding: 20px;
} - 詳細度 0-1-0-0(100点)
- 特徴 ページ内で一意の要素を特定
- 用途 ユニークな要素のスタイリング、JavaScriptとの連携
- ベストプラクティス スタイル目的での多用は避ける
クラスセレクター・属性セレクター・疑似クラス
これらのセレクターは、中程度の詳細度(10点)を持ちます。
/* クラスセレクター:詳細度 0-0-1-0 (10点) */
.button { background: green; }
/* 属性セレクター:詳細度 0-0-1-0 (10点) */
[type="submit"] { cursor: pointer; }
/* 疑似クラス:詳細度 0-0-1-0 (10点) */
a:hover { color: orange; } - 詳細度 0-0-1-0(10点)
- クラスセレクター 再利用可能なスタイルグループ
- 属性セレクター 属性値による条件指定
- 疑似クラス 状態やユーザー操作による条件指定
要素セレクター・疑似要素
要素セレクターと疑似要素は、最も低い詳細度(1点)を持ちます。
/* 要素セレクター:詳細度 0-0-0-1 (1点) */
p { margin: 1em 0; }
h1 { font-size: 2em; }
/* 疑似要素:詳細度 0-0-0-1 (1点) */
p::before { content: "★"; }
a::after { content: " →"; } - 詳細度 0-0-0-1(1点)
- 要素セレクター HTMLタグ名による基本的な指定
- 疑似要素 仮想的な要素の生成とスタイリング
- 用途 基本的なリセットCSS、デフォルトスタイル
詳細度の実践例
複数のセレクターが同じ要素を対象とした場合の詳細度比較を見てみましょう:
<div id="content" class="main-area">
<p class="intro-text">この段落は何色で表示される?</p>
</div> /* セレクターA:詳細度 0-0-0-1 (1点) */
p { color: black; }
/* セレクターB:詳細度 0-0-1-0 (10点) */
.intro-text { color: blue; }
/* セレクターC:詳細度 0-0-1-1 (11点) */
div p { color: green; }
/* セレクターD:詳細度 0-1-1-1 (111点) */
#content .intro-text { color: red; } 詳細度判定の流れ
- セレクターA
p→ 1点(要素セレクター) - セレクターB
.intro-text→ 10点(クラスセレクター) - セレクターC
div p→ 11点(要素2個 = 1+1+0+0) - セレクターD
#content .intro-text→ 111点(最高) ← 優勝!(ID1個 + クラス1個 = 0+1+1+0)
判定結果: セレクターDが最も高い詳細度を持つため、赤色が適用されます。
効果的な詳細度管理のコツ:
- クラスセレクターを中心とした設計 柔軟性と再利用性を高める
- IDセレクターの使い分け JavaScriptとの連携目的に限定
- 詳細度の段階的増加 基本→応用→特殊の順で詳細度を上げる
- !important の最小化 詳細度設計で解決を目指す
良い例:
.button { /* 基本スタイル:10点 */ }
.button.primary { /* 特殊バリエーション:20点 */ }
.header .button { /* 場所による調整:21点 */ } 宣言の出現順判定(Source Order)
出現順判定(Source Order)とは、CSSカスケードの最終ステップで、同じ詳細度のルール同士が競合した場合に、後に記述されたルールを優先する仕組みです。
これは「後勝ち」とも呼ばれ、CSSの最も基本的なルールの一つです。
ソース順序のルール
出現順判定では、以下の原則に従ってスタイルが決定されます:
- 同一ファイル内 後に書かれたルールが前のルールを上書き
- 複数ファイル間 後に読み込まれたファイルのルールが優先
- 同一セレクターが出現 同じセレクターが複数回書かれた場合、最後の記述が適用
- プロパティの扱い プロパティごとに個別に判定される
基本的な動作例
同じ詳細度のセレクターが競合する例を見てみましょう:
/* 同じ詳細度のセレクター(どちらも10点) */
.button {
background-color: blue; /* 先に記述 */
color: white;
}
.button {
background-color: red; /* 後に記述(勝利) */
padding: 10px;
} <button class="button">ボタン</button> 結果: 背景色は赤色(後勝ち)、文字色は白色、パディングは10px
この例では:
- background-color 後に書かれた赤色が適用
- color 競合しないので白色が適用
- padding 最初のルールにはないので10pxが適用
CSSファイルの読み込み順序
複数のCSSファイルがある場合
ファイルの読み込み順序も出現順に影響します:
<!-- HTML内での読み込み順序 -->
<link rel="stylesheet" href="reset.css"> <!-- 1番目 -->
<link rel="stylesheet" href="base.css"> <!-- 2番目 -->
<link rel="stylesheet" href="layout.css"> <!-- 3番目 -->
<link rel="stylesheet" href="components.css"> <!-- 4番目(最優先) --> - この場合、
components.cssが最も後に読み込まれるため、同じ詳細度のセレクターがあればcomponents.cssのルールが優先されます。
同じセレクターが複数のファイルに書かれている場合
/* base.css */
.header {
background: gray;
padding: 20px;
}
/* layout.css */
.header {
background: blue; /* base.cssを上書き */
margin: 10px;
}
/* components.css */
.header {
background: green; /* layout.cssを上書き(最終的に適用) */
} - 最終結果: 背景色は緑色、パディングは20px、マージンは10px
内部CSSと外部CSSの優先順位
HTMLファイル内での記述順序も出現順に影響します:
<!DOCTYPE html>
<html>
<head>
<!-- 外部CSS(先) -->
<link rel="stylesheet" href="style.css">
<!-- 内部CSS(後・優先) -->
<style>
.button {
background: purple;
}
</style>
</head>
<body>
<button class="button">ボタン</button>
</body>
</html> - この場合、内部CSS(
<style>タグ)が外部CSSより後に読み込まれるため、同じセレクターなら内部CSSが優先されます。
詳細度と出現順の組み合わせ
詳細度が異なる場合は、出現順に関係なく詳細度が高い方が優先されます:
/* 先に記述されているが、詳細度が高い(10点)→ 勝利 */
.text {
color: blue;
}
/* 後に記述されているが、詳細度が低い(1点) */
p {
color: red;
} <p class="text">この文字は何色?</p> 結果: 詳細度が高い.text(青色)が適用されます。
実践的な活用方法
出現順を活用したCSS設計の例:
/* 1. 基本スタイル(先に記述) */
.button {
display: inline-block;
padding: 10px 20px;
background: #ddd;
color: #333;
border: none;
border-radius: 4px;
}
/* 2. 状態による上書き(後に記述) */
.button:hover {
background: #bbb;
}
/* 3. バリエーション(さらに後に記述) */
.button.primary {
background: #007bff;
color: white;
}
.button.primary:hover {
background: #0056b3;
} この構造により、基本→状態→バリエーションの順で自然に上書きされ、予測しやすいスタイルになります。
@importの注意点
@importを使用した場合も、記述順序が重要です:
/* style.css */
@import url('reset.css'); /* 1番目 */
@import url('base.css'); /* 2番目 */
/* この後の通常のCSSルール */ /* 3番目(最優先) */
.header {
background: green;
} - @importは最上部 ファイルの先頭に記述する必要がある
- パフォーマンス注意
<link>タグの方が読み込み速度が速い - 入れ子制限 @import内で@importは使用できない
効果的な出現順活用のコツ:
- 段階的詳細化 一般的なスタイル → 具体的なスタイルの順で記述
- ファイル分割戦略 reset → base → layout → components → utilities の順
- 修正のしやすさ 後から追加するスタイルほど後ろに配置
- デバッグしやすさ 関連するスタイルをまとめて配置
/* 良い例:段階的詳細化 */
.card { /* 基本 */ }
.card.featured { /* バリエーション */ }
.card.featured:hover { /* 状態 */ }
.card.featured.urgent { /* 特殊ケース */ } 理解度チェッククイズ
CSSカスケード基本クイズ
p {
color: black;
}
.highlight {
color: blue !important;
}
p.highlight {
color: red;
} /* 外部CSS(先に読み込み) */
.container {
background: yellow;
}
/* 内部CSS(後に読み込み) */
.container {
background: green;
} /* CSS */
#main a {
color: purple;
}
.content .link {
color: orange;
}
/* HTML */
<div id="main" class="content">
<a href="#" class="link">リンク</a>
</div> まとめ
- 4段階の判定順序 起源→重要度→詳細度→出現順を正確に理解
- 詳細度の計算 インライン(1000)→ID(100)→クラス(10)→要素(1)のパターン習得
- 実践との結びつき これまで学んだ色・フォント・レイアウトでの体験と理論を統合
- デバッグ能力の向上 CSSが期待通りに動作しない原因を特定できるスキル
次回は、このカスケード知識を活用した実践的なCSS設計手法を学びます!