Spezifität

The CSS Podcast – 003: Specificity

Angenommen, Sie arbeiten mit dem folgenden HTML- und CSS-Code:

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

button {
  color: red;
}

Hier gibt es zwei Regeln, die auf dasselbe Element ausgerichtet sind. Jede Regel enthält eine Deklaration, mit der die Farbe des Buttons festgelegt werden soll: In der einen wird versucht, den Button rot zu färben, in der anderen blau. Welche Deklaration wird auf das Element angewendet?

Wenn Sie den CSS-Spezifitätsalgorithmus verstehen, wissen Sie auch, wie CSS zwischen konkurrierenden Deklarationen entscheidet.

Die Spezifität ist eine der verschiedenen Phasen der Kaskade, die im letzten Modul Die Kaskade behandelt wurde.

Bewertung der Spezifität

Jede Selektorregel innerhalb eines Ursprungs erhält eine Punktzahl. Die Spezifität kann als Gesamtwert betrachtet werden, wobei jeder Selektortyp Punkte für diesen Wert erhält. Deklarationen aus Regeln mit der höchsten Spezifität haben Vorrang.

Bei der Spezifität in einem echten Projekt besteht die Herausforderung darin, dafür zu sorgen, dass die CSS-Regeln, die Sie anwenden möchten, auch tatsächlich angewendet werden, während die Werte im Allgemeinen niedrig gehalten werden, um Komplexität zu vermeiden. Die Spezifität sollte nur so hoch sein, wie wir sie benötigen, anstatt die höchstmögliche Spezifität anzustreben. In Zukunft muss möglicherweise wichtigeres CSS angewendet werden. Wenn Sie die höchste Spezifität anstreben, wird es schwierig.

Die Spezifität ist keine Dezimalzahl, sondern ein Dreiklang aus drei Komponenten: A, B und C.

  • A: ID-ähnliche Spezifität
  • B: klassenähnliche Spezifität
  • C: elementähnliche Spezifität

Sie wird häufig mit der (A,B,C)-Notation dargestellt. Beispiel: (1,0,2) Die alternative Notation A-B-C wird ebenfalls häufig verwendet.

Ein Diagramm, das die drei Komponenten der Spezifität (A, B, C) zeigt. Für jede Komponente wird im Diagramm dargestellt, wofür sie steht, und es werden einige Beispielselektoren angegeben, die sich auf sie auswirken.
Ein Diagramm, das zeigt, welche Komponente der Spezifität von verschiedenen Selektoren betroffen ist.

Spezifitäten vergleichen

Die Spezifitäten werden verglichen, indem die drei Komponenten in der folgenden Reihenfolge verglichen werden: Die Spezifität mit einem größeren A-Wert ist spezifischer. Wenn die beiden A-Werte gleich sind, ist die Spezifität mit einem größeren B-Wert spezifischer. Wenn die beiden B-Werte ebenfalls gleich sind, ist die Spezifität mit einem größeren C-Wert spezifischer. Wenn alle Werte gleich sind, sind die beiden Spezifitäten gleich.

Beispielsweise gilt (1,0,0) als spezifischer als (0,4,3), da der A-Wert in (1,0,0) (1) größer ist als der A-Wert in (0,4,3) (0).

Selektoren beeinflussen die Spezifität

Jeder Teil des Spezifitätstrios beginnt mit dem Wert 0. Die Standardspezifität ist also (0,0,0). Jeder Teil eines Selektors erhöht die Spezifität, wodurch je nach Selektortyp der Wert von A, B oder C erhöht wird.

Universalselektor

Ein universeller Selektor (*) fügt keine Spezifität hinzu. Der Wert bleibt bei der ursprünglichen Spezifität von (0,0,0).

* {
  color: red;
}

Element- oder Pseudoelement-Selektor

Ein Element- (Typ-) oder Pseudoelement-Selektor fügt elementähnliche Spezifität hinzu, wodurch die C-Komponente um 1 erhöht wird.

Die folgenden Beispiele haben eine Gesamt-Spezifität von (0,0,1).

Typauswahl

div {
  color: red;
}

Pseudoelement-Selektor

::selection {
  color: red;
}

Klassen-, Pseudoklassen- oder Attributselektor

Ein Klassen-, Pseudoklassen- oder Attributselektor fügt klassenspezifische Spezifität hinzu, wodurch die B-Komponente um 1 erhöht wird.

Die folgenden Beispiele haben eine Spezifität von (0,1,0).

Klassenauswahl

.my-class {
  color: red;
}

Pseudoklassenselektor

:hover {
  color: red;
}

Attributauswahl

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

ID-Selektor

Ein ID-Selektor fügt ID-ähnliche Spezifität hinzu, wodurch die A-Komponente um 1 erhöht wird, sofern Sie einen ID-Selektor (#myID) und keinen Attributselektor ([id="myID"]) verwenden.

Im folgenden Beispiel ist die Spezifität (1,0,0).

#myID {
  color: red;
}

Andere Selektoren

CSS hat viele Selektoren. Nicht alle davon machen die Antwort spezifischer. Die Pseudoklasse :not() trägt beispielsweise nichts zur Berechnung der Spezifität bei.

Die Spezifität der Pseudoklasse :not() wird durch die Spezifität des spezifischsten Selektors im kommagetrennten Argument der Selektoren ersetzt. Sie entspricht der Spezifität, die sich ergeben hätte, wenn :not(:is(argument)) geschrieben worden wäre.

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

Die Pseudoklasse :is() wird auch nicht in die Berechnung der Spezifität einbezogen. Wie bei :not() wird die Spezifität des spezifischsten Arguments verwendet.

:is(h1, h2, h3) {
  color: blue;
}

Dieses Beispiel hat eine Spezifität von (0,0,1), da es nur eine Art von Selektor (type) enthält.

Durch Hinzufügen eines id steigt die Spezifität auf (1,0,0).

:is(h1, h2, h3, #my-heading) {
  color: blue;
}

Die Pseudoklasse :where() ist anders. Unabhängig von der Spezifität der Argumente hat sie immer eine Spezifität von (0,0,0).

:where(h1, h2, h3, #my-heading) {
  color: blue;
}

Die mit :where() angewendeten Stile mit geringer Spezifität ermöglichen es Ihnen, diese Stile später in Ihrem Stylesheet mit einfachen Selektoren zu überschreiben:

:where(#my-content) {
   color: red;
}

p {
   color: blue;
}

Obwohl :where() ein id in der Argumentliste hat, hat es immer noch nur eine Spezifität von (0, 0, 0). Daher wird es vom einfachen Selektor p überschrieben und der Text ist blue.

Dein Wissen wird getestet

Wissen zur Berechnung der Spezifität testen

Was ist die Spezifität von a[href=/learn/css/%22#%22%5D%3C%2Fcode>?

(0,0,1)
Der a ist (0,0,1) wert, der [href=/learn/css/%22#%22%5D%3C%2Fcode> aber (0,1,0).
(0,1,0)
Versuch es noch einmal. Der a ist (0,0,1) wert, der [href=/learn/css/%22#%22%5D%3C%2Fcode> aber (0,1,0).
(0,1,1)
Die a ist (0,0,1) wert und die [href=/learn/css/%22#%22%5D%3C%2Fcode> ist (0,1,0) wert. Das ergibt eine Gesamtspezifität von (0,1,1).

Faktoren, die sich nicht auf die Spezifität auswirken

Es gibt einige häufige Missverständnisse hinsichtlich der folgenden Faktoren, die sich auf die Spezifität auswirken.

Inline-Stilattribute

CSS, das direkt auf das Attribut style eines Elements angewendet wird, wirkt sich nicht auf die Spezifität aus, da es sich um einen anderen Schritt in der Kaskade handelt, der vor der Spezifität ausgewertet wird.

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

Wenn Sie diese Deklaration in einem Stylesheet überschreiben möchten, müssen Sie dafür sorgen, dass die Deklaration in einem früheren Schritt der Kaskade gewinnt.

Sie können beispielsweise !important hinzufügen, damit es Teil des Ursprungs „Verfasst von !important wird.

!important Erklärungen

Ein !important am Ende einer CSS-Deklaration wirkt sich nicht auf die Spezifität aus, sondern platziert die Deklaration in einem anderen Ursprung, nämlich Authored !important.

Im folgenden Beispiel ist die Spezifität von .my-class nicht relevant, damit die !important-Deklaration gewinnt.

.my-class {
  color: red !important;
  color: white;
}

Wenn zwei Deklarationen !important sind, kommt die Spezifität wieder ins Spiel, da im Ursprungsschritt der Kaskade noch kein Gewinner ermittelt werden konnte.

.branding {
  color: blue !important;
}

button {
  color: red !important;
}

Spezifität im Kontext

Wenn ein komplexer oder zusammengesetzter Selektor verwendet wird, trägt jeder Teil dieses Selektors zur Spezifität bei. Hier ein Beispiel für HTML:

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

Dieser Link enthält zwei Kurse. Die Regel im folgenden CSS hat eine Spezifität von (0,0,1):

a {
  color: red;
}

Wenn Sie im Selektor auf eine der Klassen verweisen, hat er jetzt eine Spezifität von (0,1,1):

a.my-class {
  color: green;
}

Fügen Sie die andere Klasse der Auswahl hinzu. Sie hat jetzt eine Spezifität von (0,2,1):

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

Fügen Sie dem Selektor das Attribut href hinzu. Er hat jetzt eine Spezifität von (0,3,1):

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

Fügen Sie schließlich eine :hover-Pseudoklasse hinzu. Der Selektor hat dann eine Spezifität von (0,4,1):

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

Dein Wissen wird getestet

Wissen zur Berechnung der Spezifität testen

Welcher der folgenden Selektoren hat eine Spezifität von (0,2,1)?

article > section
Elemente fügen elementspezifische Eigenschaften hinzu (C-Komponente). Der Selektor enthält zwei Elemente, sodass er eine Spezifität von (0,0,2) hat.
article.card.dark
Elemente fügen eine elementähnliche Spezifität (C-Komponente) und Klassen eine klassenähnliche Spezifität (B-Komponente) hinzu. Bei zwei Klassen und einem Element hat dieser Selektor eine Spezifität von (0,2,1).
article:hover a[href]
Elemente fügen eine elementähnliche Spezifität hinzu (Komponente „C“), Pseudoklassen und Attribute eine klassenähnliche Spezifität (Komponente „B“). Es gibt zwei Elementselektoren (2 × (0,0,1)), einen Attributselektor ((0,1,0)) und einen Klassenselektor ((0,1,0)). Die Spezifität dieses Selektors beträgt also insgesamt (0,2,2).

Pragmatische Steigerung der Spezifität

Angenommen, Sie haben CSS-Code, der so aussieht:

.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

Mit HTML, das so aussieht:

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

Der Button hat einen grauen Hintergrund, da der zweite Selektor eine Spezifität von (0,1,1) hat. Das liegt daran, dass es einen Typselektor (button), nämlich (0,0,1), und einen Attributselektor ([onclick]), nämlich (0,1,0), enthält.

Die vorherige Regel – .my-button – entspricht (0,1,0), da sie nur einen Klassenselektor hat, der eine geringere Spezifität als (0,1,1) aufweist.

Wenn Sie dieser Regel mehr Gewichtung verleihen möchten, können Sie den Klassenselektor so wiederholen:

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

button[onclick] {
  background: grey;
}

Die Schaltfläche hat jetzt einen blauen Hintergrund, da der neue Selektor eine Spezifität von (0,2,0) hat.

Bei Gleichstand in der Spezifität wird auf den nächsten Schritt in der Kaskade zurückgegriffen.

Fahren wir mit dem Schaltflächenbeispiel fort und ändern das CSS so:

.my-button {
  background: blue;
}

[onclick] {
  background: grey;
}

Die Schaltfläche hat einen grauen Hintergrund, weil beide Selektoren dieselbe Spezifität von (0,1,0) haben.

Wenn Sie die Regeln in der Quellreihenfolge tauschen, ist die Schaltfläche blau.

[onclick] {
  background: grey;
}

.my-button {
  background: blue;
}

Das liegt daran, dass beide Selektoren dieselbe Spezifität haben. In diesem Fall wird auf den Schritt „Reihenfolge der Darstellung“ zurückgegriffen.

Ressourcen