#083
posted on 2022.10.19 Wed

ひとつの要素に複数のCSS宣言が競合した場合の優先順位を決める詳細度の基礎知識。

HTML内の同一の要素に対して、CSSセレクターが色々な書き方で指定されて複数のCSS宣言が記述されているとき、どの記述のプロパティー値を適用するか決定する詳細度についての基礎知識のメモ。

※ 詳細度についてのMozillaの公式ドキュメント

 

CSS宣言は、「!important」(importantフラグ) > 「インラインスタイル」 > 「詳細度」の優先順位で適用される。
※ importantフラグを使用すると、以降はimportantフラグでしかその要素のスタイルを上書きできなくなり調整が効かなくなるので、慣習的に使用は避けられている。

 

下記のように、同一の要素にCSSで複数の異なる指定が記述されているとき、「詳細度」によってCSSの適用が決定される。

<p id="foo" class="foo">テキスト。</p>

ブラウザは、それぞれのCSSセレクターの「詳細度」を算出し、比較する。

※ この場合は「#foo」の「詳細度」が最も重いので、「color: black;」が適用される。

#foo {
	color: black;
}
body p {
	color: orange;
}
[id="foo"] {
	color: blue;
}
.foo {
	color: green;
}

 

同じ要素がCSSセレクターで明示的に複数指定されている場合だけ「詳細度」で比較される。

下記の場合、「body p」は明示されていないので、「color: orange;」を継承している「body p」と「#foo」の「詳細度」は比較されない。

※ 継承よりも直接指定の方が優先されるので「color: black;」が適用される。

body {
	color: orange;
}
#foo {
	color: black;
}

 

 

CSSの詳細度

(1) 詳細度

「詳細度」(Specificity)とは、CSSセレクターの重みを計算するアルゴリズム。

  • ある要素に対して、複数の競合するCSS宣言がある場合に、適用するCSS宣言を決定するためのルール。
  • 「詳細度」によってCSSセレクターの重みを算出・比較し、最も優先順位の高いセレクターのCSS宣言が適用される。

※ ブラウザは、カスケードのオリジンと重要度を決定した後に、「詳細度」を検討する。(※ カスケードについてのMozillaの公式ドキュメント。)

 

(2) CSSセレクター

CSSで使用される基本的なセレクターの種類。

※ セレクターのMozillaの公式ドキュメント

  • 全称セレクター : 「*」、「ns|*」、「*|*」、「|*」。
  • 要素型セレクター : 「要素名」。
  • クラスセレクター : 「.クラス名」。
  • IDセレクター : 「#id名」。
  • 属性セレクター : 「[属性名=値]」。
  • 疑似クラスセレクター : 「:疑似クラス名」。
  • 疑似要素セレクター : 「::疑似要素名」。

 

(3) セレクターの分類

「詳細度」のアルゴリズムにより、上述のCSSセレクターは「ID」、「CLASS」、「TYPE」という3つの区分のいずれかに分類される。

ひとつのCSSセレクター記述に含まれているセレクターの個数をそれぞれの区分で数え、「0-0-0」(ID – CLASS – TYPE)のように3列の値で表現される。(より左側の列の方が詳細度が重く、優先度が高い。)

  1. ID列 : 「IDセレクター」が該当。
    該当セレクターが1つなら、「ID列」の値が「1」で「1-0-0」となる。
  2. CLASS列 : 「クラスセレクター」、「属性セレクター」、「擬似クラスセレクター」が該当。
    該当セレクターが1つなら、「CLASS列」の値が「1」で「0-1-0」となる。
  3. TYPE列 : 「要素型セレクター」、「擬似要素セレクター」が該当。
    該当セレクターが1つなら、「TYPE列」の値が「1」で「0-0-1」となる。

 

[ 重み無しの例外 ]

  • 「全称セレクター」、擬似クラスの「:where()」と「その引数内のセレクター」は、重みがカウントされず、「詳細度」の計算に影響を与えない。値は「0-0-0」となる。
  • 否定擬似クラスの「:not()」と擬似クラスの「:is()」は、「詳細度」の計算においては擬似クラスと見なされないので自身に重みは無いが、「その引数内のセレクター」は重みを持つので「詳細度」に考慮される。
  • CSSセレクターの結合子(+、>, ~, ” “, ||)は、「詳細度」の重みに影響を与えない。

※ 「:where()」は値が「0-0-0」となるので、開発者が複数居る場合や、サードーパーティーとしてCSSを作成する場合などに、「詳細度」の低いCSSを作成する目的で利用される。(簡単に上書きできるようにするため。)

 

(4) 詳細度の比較

競合するCSSセレクターの「詳細度」の重みは、3列の左から順番に同じ列同士で値が比較される。

  • 1列目(ID列)を比較して、数値の大きい方が適用され、同じ数値なら2列目(CLASS列)同士を比較。
  • 数値が同じだった場合のみ、次の列が比較される。
  • 3列とも同じ数値の場合は、最後に記述されているものが適用される。

 

[ 詳細度の算出例 ]

下記のように競合した場合は、最も詳細度が重い「body p#foo」が適用される。

#foo {} /* 1-0-0 */
[id="foo"] {} /* 0-1-0 */
:where(#foo) {} /* 0-0-0 */
body #foo {} /* 1-0-1 */
p#foo {} /* 1-0-1 */
body p#foo {} /* 1-0-2 */
.foo {} /* 0-1-0 */
body p.foo {} /* 0-1-2 */
この記事をシェア
この記事のURL

https://memo.ag2works.tokyo/post-5064/

コピー
この記事のタイトル

ひとつの要素に複数のCSS宣言が競合した場合の優先順位を決める詳細度の基礎知識。 | memo メモ [AG2WORKS]

コピー
この記事のリンクタグ

<a href="https://memo.ag2works.tokyo/post-5064/" target="_blank" rel="noopener">ひとつの要素に複数のCSS宣言が競合した場合の優先順位を決める詳細度の基礎知識。 | memo メモ [AG2WORKS]</a>

コピー
※ フィールドをクリックでコピーするテキストの編集ができます。

この記事へのコメント

コメントの書き込みはまだありません。

  • コメント内のタグはエスケープ処理され、文字列として出力されます。
  • セキュリティーのため、投稿者のIPアドレスは取得されます。
  • 管理者が内容を不適切と判断したコメントは削除されます。
  • このフォームにはスパム対策として、Googleの提供するreCAPTCHAシステムが導入されています。
    (Google Privacy Policy and Terms of Service.)