このウェブサイトはご利用の端末での閲覧に対応していません。
This website does not support your device.

スタイルの継承と優先順位

記事Jul. 8th,2021
CSSのスタイルの継承と要素に複数のスタイルが適用される場合の優先順位を決めるカスケードについての解説。
この記事はCSS3に対応しています。
この記事はCSS3に対応しています。

適用されるスタイルが決まるまで

スタイルの継承

CSSではプロパティの値が要素の子要素に伝播するスタイルの“継承(Inheritance)”が起こり、継承された値は“継承値(Inherited value)”と呼ばれます。

値が継承されるかどうかはそれぞれのプロパティごとに定義されていますが、継承される場合は継承値は親要素の同じプロパティの“計算値”です。

スタイルの継承のイメージ

親要素がないルート要素(HTMLではhtml”要素)の場合、継承値はプロパティごとに定義されている初期値です。

祖先要素からの継承に加えて、スタイルシートによる指定などで一つの要素にはたくさんのスタイルの宣言が適用されることになります。その中にはプロパティが重複する宣言も含まれることになりますが、実際にスタイルが適用されるまでの間に重複する宣言の値は一つだけに絞られます。

仕様書の該当箇所

継承の明示

CSSにはスタイルの継承や初期値化を明確に示すためにいくつかの共通キーワード(CSS-wide keywords)”が定義されています。

共通キーワードはすべてのプロパティで使用することができ、本来そのプロパティが値を継承するか否かにかかわらずスタイルの継承と初期値を指定することができます。

説明
initialCSS Cascading and Inheritance Level 3 で追加 初期値を使用する
inherit 継承値を使用する
unsetCSS Cascading and Inheritance Level 3 で追加 既定で継承されるスタイルは継承値、継承されないスタイルは初期値を使用する
revertCSS Cascading and Inheritance Level 4 で追加 ユーザー・エージェント、もしくはユーザーの既定値を使用する

適用されるスタイルが決まるまで

スタイルが決まるまでの値の処理

ユーザー・エージェントが文書をパースし終えた後、すべての要素のすべてのプロパティに対象メディアに適合する値を割り当てます。

それぞれのプロパティに割り当てられる値は以下の6つの段階を経て最終的に一つが決定されます。

  1. 宣言値(Declared Values)”
  2. カスケード値(Cascaded Values)”
  3. 指定値(Specified Values)”
  4. 計算値(Computed Values)”
  5. 使用値(Used Values)”
  6. 実値(Actual Values)”
仕様書の該当箇所

宣言値

フィルタリング(Filtering)”が行われ、その要素に適用可能な宣言が集められます。適用可能な宣言は以下の条件をすべて満たした宣言です。

  1. 宣言が文書に現時点で適用されているスタイルシートに記述されている。
  2. 宣言が“CSS Conditional Rules”によるルール(@media”ルール@supports”ルール)による条件が“偽”の状態ではない。
  3. 宣言がその要素を選択するセレクタが付けられたスタイル・ルールに属している。
  4. 宣言のプロパティと値が文法的に有効である。

この結果集められた宣言の値は“宣言値(Declared Values)”と呼ばれ、この時点ではその要素に適用され得る値は複数ある可能性があります。

カスケード値

次に、“カスケード(Cascading)”が行われ、集められた宣言値から1個の値が選ばれ、この値は“カスケード値(Cascaded Values)”と呼ばれます。

カスケードの結果となる値が1個もなければ場合はカスケード値はありません。

指定値

カスケード値は“既定化(Defaulting)”処理を経て“指定値(Specified Values)”になります。指定値は制作者がその要素に適用することを意図したプロパティの値を意味します。

カスケード値が存在すれば指定値はカスケード値と同じです。カスケードの結果となる値が1個もなかった場合には既定化によって値を探します。そのプロパティの値が親要素から継承できるものであれば継承された値を使用します。値が親要素から継承できないものであればプロパティごとに定義された初期値が指定値となります。

計算値

次に、指定値はそれぞれのプロパティの仕様で定義されている“計算値”の形になるように処理され、その結果“計算値(Computed Values)”となります。

指定値は他の値に依存した相対値である場合がありますが、ほとんどの場合、計算値にする段階で相対値から算出された絶対値に置き換えられます。

要素はプロパティがその要素に適用できないものであったとしても計算値はあり、子孫要素への継承に使用されます。

使用値

計算値に残る必要な処理を行って文書を整形するのに必要な絶対的で理論的な値にしたものが“使用値(Used Values)”です。

プロパティがその要素に適用できないものである場合は使用値はありません。

実値

使用値は基本的には使用する準備ができた値ですが、ユーザー・エージェントの制約によってその値を使用することができず、使用値を調整する必要がある場合があります。そのような調整が行われた後の使用値を“実値(Actual Values)”と言います。

カスケードとスタイルの優先順位

“カスケード”について

要素に適用されるスタイルを決めるまでの間、“カスケード(Cascading)”の段階で使用する値が一つに絞られます。

複数のスタイル、例えばユーザー・エージェントの既定のスタイルと制作者が定義したスタイル、もしくは制作者が定義したスタイル同士が競合した場合にはこの過程でどのスタイルを使用するかが決定されます。

カスケード処理の過程ではその要素に適用可能な宣言値を順不同のリストとして取り込み、以下の4つを参考にして並べ替えます。

  1. 重要度(Importance)”と“カスケード・オリジン(Cascading Origins)”
  2. コンテキスト(Context)”
  3. 要素付属のスタイル(Element-Attached Styles)”
  4. レイヤー(Layers)”
  5. 詳細度(Specificity)”
  6. 記述順序(Order of Appearance)”

最終的にカスケード処理の結果はスタイルの優先順位で並べ替えられた値のリストとして出力され、リストで序列が1番になった1個の値が“カスケード値(Cascaded Values)”となり、残りの処理を経て実際に使用されるプロパティの値になります。

仕様書の該当箇所

重要度とオリジン

カスケードではまずすべての宣言を“重要度(Importance)”と“カスケード・オリジン(Cascading Origins)”によって並べ替えます。

宣言は以下の一覧の順番通りに並べ替えられます。

“CSS Transitions”による宣言
transition”プロパティなどによる遷移効果
重要なユーザー・エージェントによる宣言
!importantを値に含むユーザー・エージェント由来のスタイル
重要なユーザーによる宣言
!importantを値に含むユーザー由来のスタイル
重要な制作者による宣言
!importantを値に含む制作者由来のスタイル
“CSS Animations”による宣言
animation”プロパティなどによるアニメーション
通常の制作者による宣言
!importantを値に含まない制作者由来のスタイル
通常のユーザーによる宣言
!importantを値に含まないユーザー由来のスタイル
通常のユーザー・エージェントによる宣言
!importantを値に含まないユーザー・エージェント由来のスタイル

重要度”はスタイルの宣言に!importantフラグがあるかどうかで決まります。

カスケード・オリジン”はそのスタイルが何に由来するかを表します。すべてのスタイルにはカスケード・オリジンがあり、カスケードの過程で参考にされます。

主要なカスケード・オリジンは以下の3つが定義されています。

制作者由来(“Author Origin”)
制作者由来のスタイルは文書の記述言語によって決められた方法で文書の制作者によって定義されて適用するスタイルです。
HTMLではlink”要素style”要素style”属性によって文書に適用されるスタイルが指定されます。
ユーザー由来(“User Origin”)
何らかの方法でユーザーが文書のスタイルを指定できる場合、そのスタイルはユーザー由来です。
例えば、ユーザー・エージェントがユーザーが決めたスタイルを適用する方法を提供する場合があります。
ユーザー・エージェント由来(“User-Agent Origin”)
ユーザー・エージェントは既定のスタイルシートを適用して文書の要素を一般的に期待される表現で表示します。
例えば、HTMLの要素では一般的にh1”要素は大き目の太字で、p”要素は前後に1行分の余白を入れて表示されます。

CSSの拡張機能では以下の2つが追加のオリジンとして定義されています。

アニメーション由来(“Animation Origin”)
animation”プロパティなどによるアニメーションは実行中にその効果を表現するために疑似的なスタイル・ルールを生成します。
トランジション由来(“Transition Origin”)
transition”プロパティなどによる遷移効果は実行中にその効果を表現するために疑似的なスタイル・ルールを生成します。

コンテキスト

DOMにおけるシャドウ・ツリーなどの“カプセル化コンテキスト(Encapsulation contexts)”の場合、重要な宣言は内側のコンテキストに由来する宣言が優先され、通常の宣言は外側のコンテキストに由来する宣言が優先されます。

要素付属のスタイル

スタイルの重要度が同じ場合、“要素付属のスタイル(Element-Attached Styles)”はセレクタを使用して適用されるスタイル・ルールよりも優先されます。

要素付属のスタイルとは要素に直接指定されているスタイルのことで、HTMLでは要素にstyle”属性を使用して直接指定されたスタイルが該当します。

レイヤー

それぞれのオリジンコンテキストに含まれる宣言は明示的にカスケード・レイヤーに割り当てることができます。この時、明示的にカスケード・レイヤーに割り当てられていない宣言は暗黙的に最後のレイヤーに割り当てられます。

異なるカスケード・レイヤーに属しているスタイルの宣言は属しているカスケード・レイヤーが記述された順序によって比較されます。重要な宣言の場合は先に記述されたカスケード・レイヤーに属する宣言が優先され、通常の宣言の場合は後に記述されたカスケード・レイヤーに属する宣言が優先されます。

詳細度

次に、カスケードでは重要度とオリジンが同じ宣言を宣言が含まれるスタイル・ルールに付けられたセレクタの“詳細度(Specificity)”の高い順に並べ替えます。

  1. IDセレクタ
  2. クラス・セレクタ属性セレクタ擬似クラス
  3. タイプ・セレクタ擬似要素
  4. 全称セレクタ

詳細度は以上を順番に比較して決められます。

  1. IDセレクタの数が一番多いセレクタが一番詳細度が高くなります。
  2. IDセレクタの数が同じ場合はクラス・セレクタ属性セレクタ擬似クラスの合計数が一番多いセレクタが一番詳細度が高くなります。
  3. IDセレクタの数、クラス・セレクタ属性セレクタ擬似クラスの合計数が同じ場合はタイプ・セレクタ擬似要素の合計数が一番多いセレクタが一番詳細度が高くなります。
  4. この過程で、全称セレクタは無視されるので詳細度には影響しません。また、セレクタを結合する結合子も詳細度には影響しません。

    スタイル・ルールに含まれていない宣言(style”属性に記述された宣言など)はどのセレクタよりも高い詳細度が与えられます。

    また、セレクタがセレクタ・リストである場合にはコンマ(“,”)で区切られたセレクタはそれぞれ個別に詳細度が判断されます。

    詳細度の例
    詳細度1位
    #sample1 > #sample2 {...} /* 詳細度: 2-0-0 */
    #sample1 #sample2 {...} /* 詳細度: 2-0-0 */

    詳細度2位
    #sample > div[lang=en].sample {...} /* 詳細度: 1-2-1 */

    詳細度3位
    div#sample:first-child {...} /* 詳細度: 1-1-1 */
    div[lang=en]#sample {...} /* 詳細度: 1-1-1*/

    詳細度4位
    div#sample {...} /* 詳細度: 1-0-1 */
    div > #sample {...} /* 詳細度: 1-0-1 */

    詳細度5位
    #sample {...} /* 1-0-0 */

    詳細度6位
    div.sample:first-child {...} /* 詳細度: 0-2-1 */
    div[lang=en].sample {...} /* 詳細度: 0-2-1 */

    詳細度7位
    div.sample {...} /* 詳細度: 0-1-1*/
    div > .sample {...} /* 詳細度: 0-1-1*/

    詳細度8位
    .sample {...} /* 詳細度: 0-1-0*/

    なお、いくつかの擬似クラスは例外があります。

    仕様書の該当箇所

記述順序

最後に、重要度とオリジン、詳細度が同じ宣言をスタイルシートの中での“記述順序(Order of Appearance)”が遅い順に並べ替えます。

文書に適用されるスタイルシートが複数に分割されている場合には記述された順番は以下のように扱われます。

  1. @import”ルールで読み込まれるスタイルシートはその@import”ルールの場所に記述されているかのように扱われます。
  2. 文書に別々にリンクされているスタイルシートはリンクされている順番で連結されているかのように扱われます。HTMLではスタイルシートを読み込むlink”要素style”要素が配置されている順番の通りです。
スタイルシートの優先度のイメージ

!important

値のホワイトスペース(半角スペース(“ ”)、タブ文字など)を除いた一番最後の部分が“!”とそれに続く“!important”フラグである場合、その値を含む宣言は重要な宣言となります。

!important”フラグはすべてのプロパティで使用でき、重要な宣言はそうでない宣言よりも優先されます。

font-weight: normal !important;

重要なユーザー由来のスタイルはすべての制作者由来のスタイルを上書きします。これは文字の大きさや配色に配慮が必要なユーザーのための機能で、文書のアクセシビリティを改善します。

ユーザー・エージェント由来の重要なスタイルはすべてのユーザー由来と制作者由来のスタイルを上書きし、制作者が設定したスタイルシートでは上書きできません。

また、すべての重要な宣言はアニメーションの宣言よりも優先されます。

一番上へ
トップにもどる
シェアする
シェアする
Facebookでシェアする
ツイート
Google+でシェア
Pocket
はてなブックマーク