特異性

CSS ポッドキャスト - 003: 特異性

次の HTML と CSS を使用しているとします。

<button class="branding">Hello, Specificity!</button>
button {
  color: red;
}

.branding {
  color: blue;
}

ここには競合するルールが 2 つあります。1 つはボタンを赤、もう 1 つは青色にします。 その要素に適用されるルールはどれですか。 CSS が競合するルールをどのように決定するかを理解するには、特異性に関する CSS 仕様のアルゴリズムを理解することが重要です。

特異性は、カスケードの 4 つの異なるステージの一つです。これについては、カスケードの最後のモジュールで説明しています。

特異性スコア

各セレクタ ルールにスコアが割り当てられます。具体性は合計スコアと考えることができ、各セレクタ タイプではそのスコアのポイントを獲得します。 スコアが最も高いセレクタが優先されます。

実際のプロジェクトでは特異性が高いため、想定している CSS ルールが実際に適用されるようにする一方で、複雑さを防ぐために一般的にスコアを低く抑えるというバランス調整が行われます。スコアは、可能な限り高いスコアを目指さないでください。将来的には、より本当に重要な CSS の適用が必要になる場合があります。最高スコアになれば、その仕事はむずかしくなるでしょう。

セレクタの種類ごとのスコア

セレクタのタイプごとにポイントを獲得します。 これらのすべてのポイントを加算して、セレクタの全体的な特異性を計算します。

ユニバーサル セレクタ

ユニバーサル セレクタ*)は特異性はなく、0 ポイントです。つまり、点数が 1 つ以上のルールが優先されます

* {
  color: red;
}

要素または疑似要素セレクタ

要素(タイプ)または疑似要素セレクタには、1 つの特異性があります。

タイプセレクタ

div {
  color: red;
}

疑似要素セレクタ

::selection {
  color: red;
}

クラス、疑似クラス、または属性セレクタ

クラス疑似クラス、または属性セレクタには、10 ポイントの特異性があります。

クラスセレクタ

.my-class {
  color: red;
}

疑似クラス セレクタ

:hover {
  color: red;
}

属性セレクタ

[href='#'] {
  color: red;
}

:not() 疑似クラス自体は、特異性の計算には何の追加もしません。ただし、引数として渡されたセレクタは、特異性の計算に追加されます。

div:not(.my-class) {
  color: red;
}

このサンプルでは、1 つの型セレクタ(div)と :not()の 1 つのクラスがあるため、11 ポイントの特異性があります。

ID セレクタ

属性セレクタ([id="myID"])ではなく ID セレクタ(#myID)を使用している限り、ID セレクタには100 ポイントの特異性があります。

#myID {
  color: red;
}

インライン スタイルの属性

HTML 要素の style 属性に直接適用された CSS は、特異性スコア 1,000 ポイントを獲得します。つまり CSS でオーバーライドするには 具体的なセレクタを記述する必要があります

<div style="color: red"></div>

!important ルール

最後に、CSS 値の末尾の !important の特異性スコアは 10,000 ポイントです。これは、個々のアイテムに適用できる最も高い特異性です。

!important ルールは CSS プロパティに適用されるため、ルール全体のすべて(セレクタとプロパティ)の特異性スコアが同じになるわけではありません。

.my-class {
  color: red !important; /* 10,000 points */
  background: white; /* 10 points */
}

理解度チェック

特異性スコアの知識をテストする

a[href="#"] の特異性スコアは?

1
a は 1 ポイント、[href="#"] は 10 ポイントです。
5
もう一度考えてみましょう。
11
a は 1 ポイント、[href="#"] は 10 ポイント、合計スコアは 11 ポイントです。

コンテキスト内の具体性

要素に一致する各セレクタの特異性が加算されます。次の HTML の例で考えてみましょう。

<a class="my-class another-class" href="#">A link</a>

このリンクには 2 つのクラスがあります。以下の CSS を追加すると、特定の 1 ポイントが与えられます。

a {
  color: red;
}

このルールのクラスの 1 つを参照すると、11 の特異性が追加されました。

a.my-class {
  color: green;
}

もう一方のクラスをセレクタに追加すると、21 の特異性を持つようになります。

a.my-class.another-class {
  color: rebeccapurple;
}

href 属性をセレクタに追加すると、31 の特異性を持つようになりました。

a.my-class.another-class[href] {
  color: goldenrod;
}

最後に、これらすべてに :hover 疑似クラスを追加すると、セレクタは最終的に 41 ポイントの特異性を持つようになります。

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

理解度チェック

特異性スコアの知識をテストする

21 ポイントに該当するセレクタは、次のうちどれですか。

article > section
要素は 1 ポイント、セレクタには 2 つの要素があるため、2 ポイントに相当します。
article.card.dark
要素は 1 ポイント、クラスは 10 ポイント、2 つのクラスと 1 つの要素があるため、このセレクタの価値は 21 ポイントとなります。
article:hover a[href]
要素は 1 ポイント、擬似クラスと属性は 10 ポイント、要素には 2 ポイント、属性とクラスには 20 ポイントがあるため、このセレクタには 22 ポイントの価値があります。

特異性の可視化

図や特異度計算ツールでは、多くの場合、特異度は次のように視覚化されます。

セレクタが最も限定的であることから、最も限定的でないセレクタを示す図

左側のグループは id セレクタです。 2 つ目のグループは、クラス、属性、疑似クラス セレクタです。最後のグループは、要素セレクタと疑似要素セレクタです。

参考として、次のセレクタは 0-4-1 です。

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

理解度チェック

特異性の可視化に関する知識をテストする

次のセレクタのうち、1-2-1 はどれですか?

section#specialty.dark
このセレクタは 1-1-1 として可視化されます。
#specialty:hover li.dark
🎉
[data-state-rad].dark#specialty:hover
このセレクタは 1-3-0 として可視化されます。
li#specialty section.dark
このセレクタは 1-1-2 として可視化されます。

特異性を実用的に高める

次のような CSS があるとします。

.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

次のような HTML を使用します。

<button class="my-button" onclick="alert('hello')">Click me</button>

2 番目のセレクタは 11 ポイントの特異性0-1-1)を獲得するため、ボタンの背景はグレーになります。これは、1 つのタイプセレクタ(button(1 ポイント)と属性セレクタ([onclick](10 ポイント)があるためです。

前のルール(.my-button)にはクラスセレクタが 1 つあるため、10 ポイント0-1-0)が付与されます。

このルールの効果を高めるには、クラスセレクタを次のように繰り返します。

.my-button.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

これで、新しいセレクタの特異性スコアが 20 ポイント0-2-0)になるため、ボタンの背景が青色になります。

特異性スコアが一致する場合は、最新のインスタンスが優先されます

今はボタンの例に着手して、CSS を次のように切り替えましょう。

.my-button {
  background: blue;
}

[onclick] {
  background: grey;
}

両方のセレクタの特異性スコアが同一0-1-0)であるため、ボタンの背景はグレーです。

ソースの順序でルールを切り替えると、ボタンは青色になります。

[onclick] {
  background: grey;
}

.my-button {
  background: blue;
}

これは、新しい CSS が優先される唯一のインスタンスです。そのためには、同じ要素をターゲットとする別のセレクタの特異性を一致させる必要があります。

関連情報