The CSS Podcast - 004: The Cascade

CSS は、カスケーディング スタイルシートの略です。カスケードは、HTML 要素に複数の CSS ルールが適用される場合の競合を解決するアルゴリズムです。そのため、次の CSS でスタイル設定されたボタンのテキストは青色になります。

button {
  color: red;
}

button {
  color: blue;
}

カスケード アルゴリズムを理解すると、ブラウザがこのような競合を解決する仕組みを理解できます。カスケード アルゴリズムは 4 つの異なるステージに分かれています。

  1. 表示位置と順序: CSS ルールの表示順序
  2. Specificity: 最も一致度の高い CSS セレクタを決定するアルゴリズム
  3. オリジン: CSS が表示される順序とその出所(ブラウザ スタイル、ブラウザ拡張機能の CSS、作成した CSS など)
  4. 重要度: 一部の CSS ルールは、他のルールよりも重み付けが高くなります(特に !important ルールタイプの場合)。

表示位置と表示順序

CSS ルールの表示順序と表示方法は、競合解決の計算中にカスケードによって考慮されます。これはカスケードの最後のステップであり、常に 1 つの宣言が勝者になります。ただし、位置は、カスケードの他のすべてのステップが考慮された後もスタイルの競合が残っている場合にのみ考慮されます。

このレッスンの冒頭のデモは、位置の最もわかりやすい例です。重要度のない作成者起源のルールが 2 つあります。どちらもレイヤ化されておらず、限定性が同じセレクタを持つルールから取得されているため、最後に宣言されたルールが優先されます。

スタイルは、HTML ページ上のさまざまなソース(<link> タグ、埋め込み <style> タグ、@import ルール、要素の style 属性で定義されたインライン CSS など)から取得できます。

HTML ページの上部に CSS を含む <link> があり、ページの下部に CSS を含む別の <link> がある場合、下部の <link> のスタイルの方が優先されます。埋め込まれた <style> 要素や、1 つの style 属性内の競合する宣言でも同じことが起こります。カスケードの他のすべてのステップが同じ場合、最後のスタイルが優先されます。

ボタンの背景は青色で、<link /> 要素に含まれる CSS で定義されています。暗く設定する CSS ルールが 2 つ目のリンクされたスタイルシートにあり、後ろにあるため適用されます。

この順序は、埋め込まれた <style> 要素にも適用されます。<link> の前に宣言されている場合、リンクされたスタイルシートの CSS が優先されます。

<style> 要素は <head> で宣言され、<link /> 要素は <body> で宣言されます。つまり、<style> 要素よりも限定性が高くなります。

style 属性に関連するセレクタの順序は重要ではありません。これらの競合は、カスケードの要素の接続ステップで解決されるためです。ただし、同じスタイル属性内の複数の宣言は、引き続き位置情報に基づいて優先度を決定できます。

位置も CSS ルールの順序で適用されます。この例では、background: purple が最後に宣言されているため、要素の背景は紫色になります。緑色の背景は紫色の背景より前に宣言されているため、ブラウザによって無視されます。

.my-element {
  background: green;
  background: purple;
}

同じプロパティに 2 つの値を指定できるため、特定の値をサポートしていないブラウザ用のフォールバックが簡単に作成できます。次の例では、font-size が 2 回宣言されています。ブラウザで clamp() がサポートされている場合、以前の font-size 宣言は無視されます。ブラウザで clamp() がサポートされていない場合、最初の宣言が適用され、font-size は 1.5rem になります。

.my-element {
  font-size: 1.5rem;
  font-size: clamp(1.5rem, 1rem + 3vw, 2rem);
}

理解度を確認する

カスケードの知識をテストする

ページに次の HTML がある場合:

<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="/styles.css" />
  </head>
  <body>
    <button>I am a button</button>
    <style>
      button {
        background: pink;
      }
    </style>
  </body>
</html>

styles.css 内には、次の CSS ルールがあります。

button {
  background: yellow;
}

ボタンの背景の色は何色ですか?

ピンク
埋め込まれた <style> のオリジンは <link> タグよりもページの下部にあるため、button の特定度は同じですが、スタイルルールの位置が優先されます。
HTML ドキュメントでは、黄色のボタンの背景が最初に読み取られた可能性がありますが、後で同じ特定度の新しいルールが検出され、このルールがボタンに適用されなくなりました。

特異性

詳細度は、重み付けまたはスコアリング システムを使用して計算を行い、最も具体的な CSS セレクタを選択するアルゴリズムです。ルールをより具体的にすることで、セレクタに一致する他の CSS が CSS の後半にあっても、そのルールが適用されるようにできます。

次のレッスンでは、特異性の計算方法について詳しく説明します。ただし、いくつかの点を考慮することで、特異性に関する問題を回避できます。

要素のクラスをターゲットとする CSS は、要素のみをターゲットとする CSS よりもそのルールがより具体的になるため、適用する優先度が高くなります。つまり、次の CSS では、両方のルールが一致し、h1 セレクタのルールがスタイルシートの後半にあるにもかかわらず、h1 は赤色になります。

<h1 class="my-element">Heading</h1>
.my-element {
  color: red;
}

h1 {
  color: blue;
}

id を使用すると CSS の適用範囲がさらに絞り込まれるため、ID に適用されたスタイルは、他の方法で適用されたスタイルよりも優先されます。これが、id にスタイルを適用することが一般的に推奨されない理由の一つです。そのスタイルを他のスタイルで上書きするのが難しくなる可能性があります。

特異性は累積的

次のレッスンで説明するように、各タイプのセレクタには、そのセレクタの特定度を示すポイントが付与されます。要素のターゲティングに使用したすべてのセレクタのポイントが合計されます。つまり、a.my-class.another-class[href]:hover などのセレクタリストで要素をターゲットにすると、他の CSS で上書きするのが非常に難しくなります。このため、また CSS をより再利用できるようにするために、セレクタはできるだけシンプルにすることをおすすめします。必要に応じて要素にアクセスするためのツールとして特定度を使用しますが、長くて特定のセレクタリストは、可能であれば常にリファクタリングを検討してください。

出発地

ページに適用される CSS は、記述した CSS だけではありません。カスケードでは、CSS の起源が考慮されます。このオリジンには、ブラウザの内部スタイルシート、ブラウザ拡張機能またはオペレーティング システムによって追加されたスタイル、作成した CSS が含まれます。これらのオリジンの具体性の順序は、具体性が低い順に次のとおりです。

  1. ユーザー エージェント ベースのスタイル。これらは、ブラウザが HTML 要素にデフォルトで適用するスタイルです。
  2. ローカル ユーザーのスタイル。これらは、ベースフォントサイズやモーションの低減設定など、オペレーティング システム レベルで設定できます。ブラウザ拡張機能(ユーザーがウェブページに独自のカスタム CSS を記述できるブラウザ拡張機能など)から取得されることもあります。
  3. 作成した CSS。作成した CSS。
  4. 作成者 !important。作成した宣言に追加した !important です。
  5. ローカル ユーザー スタイル !important。オペレーティング システム レベルまたはブラウザ拡張機能レベルの CSS から取得された !important
  6. ユーザー エージェント !important。ブラウザから提供されるデフォルトの CSS で定義されている !important

リストでも説明されているように、送信元の順序を視覚的に示しています。

作成した CSS に !important ルールタイプがあり、ユーザーがカスタム CSS に !important ルールタイプを持っている場合、どちらの CSS が優先されますか?

理解度を確認する

カスケードの起源に関する知識をテストする

カスケードの起源に関する知識をテストし、さまざまな起源の次のスタイルルールについて考えてみましょう。

ユーザー エージェント スタイル

h1 { margin-block-start: 0.83em; }

ブートストラップ

h1 { margin-block-start: 20px; }

ページ作成者のスタイル

h1 { margin-block-start: 2ch; }

@media (max-width: 480px) {
  h1 { margin-block-start: 1ch; }
}

ユーザーのカスタム スタイル

h1 { margin-block-start: 2rem !important; }

次に、次の HTML があるとします。

<h1>Lorem ipsum</h1>

h1 の最後の margin-block-start は何ですか?

20px
ブートストラップは作成元の一部であり、重要なローカル ユーザー スタイルに負けます。
0.83em
ユーザー エージェントのスタイルのオリジンが、重要なローカル ユーザー スタイルに負ける。
2rem
この !important ユーザー カスタム スタイルは、最も具体的な送信元です。
2ch
この作成者スタイルは作成元の一部であり、重要なローカル ユーザー スタイルに負けます。
1ch
この作成者スタイルは作成元の一部であり、重要なローカル ユーザー スタイルに負けます。

重要度

すべての CSS ルールが同じ方法で計算されるわけではありません。また、同じ詳細度が設定されるわけではありません。

重要度の順序は、重要度が低い順から次のとおりです。

  1. 通常のルールタイプ(font-sizebackgroundcolor など)
  2. animation ルールの種類
  3. !important ルールタイプ(オリジンと同じ順序)
  4. transition ルールの種類

アクティブなアニメーションと遷移のルールタイプは、通常のルールよりも重要度が高くなります。遷移の場合、!important ルールタイプよりも重要度が高い。これは、アニメーションまたは遷移がアクティブになると、視覚的な状態が変化することが想定されるためです。

DevTools を使用して、一部の CSS が適用されない理由を確認する

通常、ブラウザ DevTools には、要素に一致する可能性のあるすべての CSS が表示され、使用されていない CSS は取り消し線が引かれます。

上書きされた CSS が取り消し線で示されているブラウザ DevTools。

適用する予定の CSS がまったく表示されない場合は、要素と一致していません。その場合は、クラス名や要素名の誤字脱字や無効な CSS など、他の原因を探す必要があります。

理解度を確認する

カスケードの知識をテストする

カスケードは次の用途に使用できます。

要素に複数のスタイルが適用された場合の競合の解決。
これは、競合解決という主な目標の 1 つです。
描画時にプロパティごとにスタイル値が 1 つだけになるようにします。
テキストの色は 1 色にする必要があります。カスケードは、どの色にするか決定する方法です。
スコアリングと重み付けのスタイルルール。
スコアリングと重み付けは、カスケードの並べ替えフェーズに含まれます。
スタイル属性の並べ替えとフィルタリング。
並べ替えとフィルタリングは、競合解決の側面を理解するのに役立つカスケードのフェーズです。

リソース