CSS
カスケーディングと特異性
サーチ…
備考
CSSの特異性は、幅広い要素セットの一般的な書式設定規則を作成者が定義できるようにすることでコードの簡潔さを促進し、特定の部分集合に対してオーバーライドすることを意図しています。
カスケーディング
カスケーディングと特異性は、CSSスタイリングプロパティの最終的な値を決定するために一緒に使用されます。また、CSSルールセットの競合を解決するためのメカニズムも定義します。
CSS読み込み順
スタイルは次のソースから順に読み込まれます。
- ユーザーエージェントのスタイルシート(ブラウザベンダが提供するスタイル)
- ユーザースタイルシート(ユーザーが自分のブラウザーで設定した追加のスタイル設定)
- 著者スタイルシート(著者はウェブページ/ウェブサイトの作成者を意味する)
- たぶん1つ以上の
.css
ファイル - HTMLドキュメントの
<style>
要素
- たぶん1つ以上の
- インラインスタイル(HTML要素の
style
属性)
ブラウザは、要素をレンダリングするときに対応するスタイルをルックアップします。
競合はどのように解決されますか?
1つのCSSルールセットだけが要素のスタイルを設定しようとすると、競合はなく、そのルールセットが使用されます。
競合する設定で複数のルールセットが見つかった場合は、最初にSpecifictyルール、次にカスケードルールを使用して、使用するスタイルを決定します。
例1 - 特異性ルール
.mystyle { color: blue; } /* specificity: 0, 0, 1, 0 */
div { color: red; } /* specificity: 0, 0, 0, 1 */
<div class="mystyle">Hello World</div>
テキストはどのような色になりますか? (ホバーして答えを見る)
青
最初に、特異性規則が適用され、最も特異性の高いものが「勝つ」。
例2 - 同じセレクタを持つカスケード規則
外部のCSSファイル
.class {
background: #FFF;
}
内部CSS(HTMLファイル内)
<style>
.class {
background: #000;
}
<style>
この場合、セレクタが同一の場合、カスケードが起動し、最後にロードされたものが「勝つ」と判断されます。
例3 - 特異性ルールの後のカスケードルール
body > .mystyle { background-color: blue; } /* specificity: 0, 0, 1, 1 */
.otherstyle > div { background-color: red; } /* specificity: 0, 0, 1, 1 */
<body class="otherstyle">
<div class="mystyle">Hello World</div>
</body>
背景はどのような色ですか?
赤
特定ルールを適用した後も、青と赤の間にはまだ競合があるため、カスケードルールは特定ルールの上に適用されます。カスケーディングは、同じ.css
ファイル内か、スタイルソースのコレクション内かに関係なく、ルールのロード順を調べます。最後にロードされたものは、以前のものより優先されます。この場合、 .otherstyle > div
ルールが「勝つ」。
最後のメモ
- セレクターの特異性は常に優先されます。
- スタイルシート順序のブレークタイ。
- インラインスタイルはすべてを凌駕します。
!重要な宣言
!important
宣言は、ルールに高い優先度を与えることによって、スタイルシートの通常の特異性を上書きするために使用されます。その使用法は次の通りです: property : value !important;
#mydiv {
font-weight: bold !important; /* This property won't be overridden
by the rule below */
}
#outerdiv #mydiv {
font-weight: normal; /* #mydiv font-weight won't be set to normal
even if it has a higher specificity because
of the !important declaration above */
}
!important
の使用を避けることは、あなたのスタイルシートに不確実性をもたらすCSSルールの自然な流れを妨げるため、(絶対に必要でない限り)強くお勧めします。また、 !important
宣言が複数の要素に対して同じ規則に複数適用された場合、より高い特異性を持つ宣言が適用されることに注意することが重要です。
!important
宣言を正当化できるいくつかの例を以下に示します。
- html要素の
style
属性の内側に記述されている要素のインラインスタイルによってルールをオーバーライドしてはならない場合。 -
!important
を使って作者のスタイルを上書きすることにより、フォントサイズの増減など、Webアクセシビリティをより詳細に制御できるようにする。 - inspect要素を使ったテストとデバッグ用。
参照:
セレクター特異性の計算
個々のCSSセレクタにはそれぞれ固有の値があります。配列中の各セレクターは、配列の全体的特異性を増加させる。セレクターは、 A 、 Bおよびcの3つの異なる特異性グループの1つに分類される。複数のセレクタシーケンスが特定の要素を選択するとき、ブラウザは全体的な特異性が最も高いシーケンスによって適用されるスタイルを使用します。
グループ | から成って | 例 |
---|---|---|
A | IDセレクタ | #foo |
B | クラスセレクタ 属性セレクタ 疑似クラス | .bar [title] 、 [colspan="2"] :hover 、 :nth-child(2) |
c | タイプセレクタ 擬似要素 | div 、 li ::before 、 ::first-letter |
グループAが最も特異的であり、次にグループB 、次いでグループcが続きます 。
普遍的なセレクター( *
)とコンビネーター( >
や~
ような)は特異性がありません。
例1:様々なセレクター配列の特異性
#foo #baz {} /* a=2, b=0, c=0 */
#foo.bar {} /* a=1, b=1, c=0 */
#foo {} /* a=1, b=0, c=0 */
.bar:hover {} /* a=0, b=2, c=0 */
div.bar {} /* a=0, b=1, c=1 */
:hover {} /* a=0, b=1, c=0 */
[title] {} /* a=0, b=1, c=0 */
.bar {} /* a=0, b=1, c=0 */
div ul + li {} /* a=0, b=0, c=3 */
p::after {} /* a=0, b=0, c=2 */
*::before {} /* a=0, b=0, c=1 */
::before {} /* a=0, b=0, c=1 */
div {} /* a=0, b=0, c=1 */
* {} /* a=0, b=0, c=0 */
例2:ブラウザがどのように特異性を使用するか
以下のCSS実装を想像してみてください。
#foo {
color: blue;
}
.bar {
color: red;
background: black;
}
ここでは、宣言IDセレクタ有するcolor
青色として、と宣言するクラスセレクタcolor
赤としてbackground
ブラック等を。
IDを持つ要素#foo
のクラス.bar
両方の宣言によって選択されるであろう。 IDセレクターはグループA特異性を有し、クラスセレクターはグループB特異性を有する。 IDセレクタは、任意の数のクラスセレクタを上回ります。このため、 color:blue;
#foo
セレクタとbackground:black;
.bar
セレクタからの要素が要素に適用されます。 IDセレクタの特異度が高いほど、ブラウザは.bar
セレクタのcolor
宣言を無視します。
CSSのさまざまな実装を想像してみましょう。
.bar {
color: red;
background: black;
}
.baz {
background: white;
}
ここには2つのクラスセレクタがあります。一つは宣言color
赤としてbackground
ブラックとして、他方が宣言background
白として。
両方を持つ要素.bar
と.baz
クラスはこれらの宣言の両方によって影響を受けることになるが、しかし、我々が今持っている問題は、その両方で.bar
と.baz
同じグループB特異性を持っています。 CSSのカスケード性質は、私たちのためにこれを解決しますよう.baz
後に定義されて.bar
、私たちの要素が赤で終わるcolor
から.bar
が、 白い background
から.baz
。
例3:特異性を操作する方法
上記実施例2からの最後の断片は、私たちを保証するために操作することができる.bar
クラスセレクタのcolor
宣言が代わりのものを用いている.baz
クラスセレクタ。
.bar {} /* a=0, b=1, c=0 */
.baz {} /* a=0, b=1, c=0 */
これを実現する最も一般的な方法は、 .bar
セレクタシーケンスに適用できる他のセレクタを見つけることです。たとえば、 .bar
クラスがspan
要素にのみ適用された場合、 .bar
セレクタをspan.bar
変更できます。これにより、 .baz
セレクタの欠如を無効にする新しいグループCの特殊性が与えられます。
span.bar {} /* a=0, b=1, c=1 */
.baz {} /* a=0, b=1, c=0 */
しかし、 .bar
クラスを使用する要素間で共有される別の共通セレクタを見つけることは必ずしも可能ではないかもしれません。このため、CSSではセレクタを複製して特異性を高めることができます。代わりに、ただの.bar
、我々は使用することができます.bar.bar
代わりに(参照してくださいセレクタの文法、W3C勧告 )。これは.bar
クラスを持つ要素を選択しますが、グループBの特殊性を2倍にしました:
.bar.bar {} /* a=0, b=2, c=0 */
.baz {} /* a=0, b=1, c=0 */
!important
でインラインスタイルの宣言
スタイル宣言の!important
フラグとHTML style
属性で宣言されたスタイルは、どのセレクタよりも高い特異性を持つと見なされます。これらが存在する場合、影響を受けるスタイル宣言は、その特異性に関係なく他の宣言を無効にします。つまり、同じ要素に適用される同じプロパティに対して!important
フラグを含む宣言が複数ある場合を除きます。そして、それらの特性に対して、互いに特異的な規則が適用されます。
彼らは特異性を完全に無効にするので、大部分のユースケースでは!important
の使用は戸惑うことになります。できるだけそれを使うべきではありません。長期間に渡ってCSSコードを効率的かつ保守可能に保つには、 !important
を使用するよりも、周囲のセレクタの特異性を高める方が良いでしょう。
これらのまれな例外のうちの1つは、 !important
悩まされていませんが、遭遇したときに常に1つ以上のプロパティをオーバーライドするはずの.hidden
または.background-yellow
クラスのようなジェネリックヘルパークラスを実装するときです。それでも、あなたがしていることを知る必要があります。メンテナンス可能なCSSを書くときに最後に望むことは、CSS全体に!important
フラグを付けることです。
最後のメモ
CSSの特異性に関する一般的な誤解は、グループA 、 B 、およびCの値を組み合わせる必要があるということです( a=1, b=5, c=1
=> 151)。これは当てはまりません 。これが当てはまる場合、グループBまたはCセレクターの20個を有することは、それぞれ単一のグループAまたはBセレクターをオーバーライドするのに十分である。 3つのグループは個別レベルの特異性とみなすべきである。特異性は単一の値で表現することはできません。
CSSスタイルシートを作成するときは、できるだけ特異性を低く保つ必要があります。他のメソッドを上書きするために特異性を少し高くする必要がある場合は、それを高くするために可能な限り低くします。次のようなセレクタを持つ必要はありません。
body.page header.container nav div#main-nav li a {}
これにより、将来の変更がより困難になり、そのCSSページが汚染されます。
より複雑な特異性の例
div {
font-size: 7px;
border: 3px dotted pink;
background-color: yellow;
color: purple;
}
body.mystyle > div.myotherstyle {
font-size: 11px;
background-color: green;
}
#elmnt1 {
font-size: 24px;
border-color: red;
}
.mystyle .myotherstyle {
font-size: 16px;
background-color: black;
color: red;
}
<body class="mystyle">
<div id="elmnt1" class="myotherstyle">
Hello, world!
</div>
</body>
どのような罫線、色、フォントサイズがテキストになりますか?
フォントサイズ:
font-size: 24;
#elmnt1
ルールセットは問題の<div>
に対して最も高い特異性を持つため、ここのすべてのプロパティが設定されます。
境界:
border: 3px dotted red;
。ボーダーカラーのred
は#elmnt1
ルールセットから取得されます。これは最も高い特異性を持つためです。 border、border-thickness、border-styleの他のプロパティは、div
ルールセットからのものです。
背景色:
background-color: green;
。background-color
は、div
、body.mystyle > div.myotherstyle
、および.mystyle .myotherstyle
ルールセットで設定されます。特異性は(0、0、1)対(0,2,2)対(0,2,0)であるため、中間のものが「勝つ」。
色:
color: red;
。色は、div
.mystyle .myotherstyle
と.mystyle .myotherstyle
両方で設定されます。後者は(0、2、0)と "勝利"の高い特異性を持っています。