CSS-Spezifität
Wenn ihr schon einmal einen CSS-Befehl geschrieben habt, der aus unerklärlichen Gründen vom Browser ignoriert wurde, könnte die CSS-Spezifität dafür verantwortlich sein. Je spezifischer ein CSS-Selektor geschrieben ist, desto stärker ist er.

Wenn Ihr die volle Kontrolle über euren CSS-Code erlangen wollt und gleichzeitig die Code-Qualität eurer Website verbessern möchtet, solltet ihr wissen was CSS-Spezifität ist. Die CSS-Spezifität beschreibt die unterschiedliche Gewichtung von CSS-Selektoren und hilft euch dabei zu verstehen welchen Selektor der Browser interpretiert.
Wenn ihr schon einmal einen CSS-Befehl geschrieben habt, der aus unerklärlichen Gründen vom Browser ignoriert wurde ist dieser Artikel sicher hilfreich. Wenn ihr schon einmal den !important
-Befehl verwendet habt, weil ein Effekt anders nicht erreicht werden konnte, ist dieser Artikel Pflicht.
Browser lesen von oben nach unten
Wenn ein CSS-Selektor mehrfach im Dokument steht gibt es einen Konflikt. In diesem Fall interpretiert der Browser immer die zuletzt notierte Regel. Eine im Stylesheet unten notierte Regel überschreibt also alle zuvor notierten identischen Selektoren. Das folgende Beispiel zeigt einen typischen Fall. Das Link-Element würde hier rot dargestellt.
#nav-main ul li a {
color:black;
}
#nav-main ul li a {
color:red;
}
CSS-Spezifität
Eine CSS-Regel wird nur dann von einer weiter unten notierten Regel überschrieben, wenn beide Selektoren identisch sind und das gleiche „Gewicht“ haben.
Jede ID, jede Klasse und jedes HTML-Element (Tag) hat ein festgelegtes Gewicht das nicht verändert werden kann. Das Gewicht des gesamten CSS-Selektors bestimmt sich durch die Summe der einzelnen Bestandteile. Der Browser interpretiert im Konfliktfall immer die Regel mit dem höchsten Gewicht, auch wenn diese Regel weiter oben im Quellcode steht. Dieses Verhalten nennt man CSS-Spezifität.
Damit ihr berechnen könnt welcher Selektor vom Browser interpretiert wird müsst ihr natürlich wissen welches Gewicht die einzelnen Elemente haben. Folgende Punktwerte vereinfachen das Verständnis der W3C-Spezifikation.
- HTML-Elemente (z.b.
h1
,p
,blockquote
) = 1 Punkt - CSS-Klassen (z.B.
.alert
,.js
) = 10 Punkte - Pseudo-Klassen/Elemente (z.B.
:nth-of-type
) = 10 Punkte - CSS-IDs (z.B.
#container
,#header
) = 100 Punkte - Inline-Styles (z.B.
<h1 style="color: red;"></h1>
) = 1000 Punkte - !important
!important
gewinnt immer, es sei denn mehere Selektoren haben ein!important
erhalten.
Das folgende Beispiel zeigt einen weiteren typischen Anwendungsfall. Stellt euch einen Header mit enthaltener Hauptnavigation vor:
#header a {
color:black;
}
ul.nav-main li.active a {
color:red;
}
Der obere Selektor hat ein Gewicht von 101 (100 + 1), der untere Selektor hat ein Gewicht von 23 (1 + 10 + 1 + 10 + 1). Die Links in der Navigation werden daher schwarz dargestellt. Die untere Regel wird überschrieben, da sie weniger Gewicht hat.

Verschiedene Beispiele
.js nav#nav-main li { ... }
Der Selektor hat ein Gewicht von 112 (10 + 1 + 100 + 1).
blockquote p a { ... }
Der Selektor hat ein Gewicht von 3 (1 + 1 + 1).
.author h1 {}
Der Selektor hat ein Gewicht von 11 (10 + 1).
ul li:nth-of-type(odd) { ... }
Der Selektor hat ein Gewicht von 12 (1 + 1 + 10).
!important
Wenn eine Eigenschaft unbedingt angezeigt werden soll, könnt ihr !important
verwenden. In diesem Fall wird ein identischer Selektor ohne !important
überschrieben. Achtet allerdings darauf, dass ihr diese Methode sparsam oder besser gar nicht einsetzt.
#nav-main ul li a {
color:black !important;
}
#nav-main ul li a {
color:red;
}
In diesem Beispiel wird die obere Regel interpretiert, da sie identisch zur unteren Regel ist und ein !important
enthält.
Attributselektoren statt IDs
Wenn ihr die Spezifität niedrig halten möchtet ohne auf IDs zu verzichten, verwendet Attributselektoren. Die Gewichtung der Selektoren findet ja im CSS-Code statt und nicht im HTML-Markup. Achtet bei dieser Technik allerdings auf den Browser-Support für Attributselektoren.
[id="nav-main"] { … }
anstelle von:
#nav-main { … }
Fazit
Wenn ihr die CSS-Spezifität beherrscht, kann das sehr positive Auswirkungen auf die Code-Qualität eurer Websites haben. Selektoren mit geringen Gewicht sollten im Dokument möglichst weit nach oben geschrieben werden, da diese Elemente häufig später überschrieben werden. Da IDs im Vergleich zu Klassen ein sehr hohes Gewicht haben (100 zu 10) solltet ihr darauf achten nicht zu viele IDs einzusetzen.
Die Holzhammermethode !important
und Inline-Styles sollten nach Möglichkeit gar nicht eingesetzt werden, da sie sich nur sehr schwer wieder überschreiben lassen und dem Dokument Flexibilität nehmen.
Tools
Mit dem CSS Specificity Graph Generator, könnt ihr euer Stylesheet untersuchen und in einen visuellen Graphen umwandeln lassen. Je flacher die Kurve, desto niedriger die CSS-Spezifität.
Mit CSS Explain kann die Gewichtung eines Selektors berechnet werden. Auch die Auswirkung auf die Performance wird in Form eines farbigen Balkens dargestellt.
Ein feine Übersicht, klar und verständlich zusammengefasst. Bei Einsatz relativ großer Stylesheets (z.Bsp. Magento) sowie beim Bearbeiten dieser von mehreren Personen ist es unabkömmlich, zu wissen, welche Gewichtung verschiedene Selektoren haben. Wenn man nicht selber geschriebenen CSS-Code bearbeitet – der ggf. auch schlecht dokumentiert ist – kann es manchmal schon recht müßig sein, havarierende Selektoren zu lokalisieren und zu kitten.
Auch von mir: eine klasse Blog hier!
Toll Danke ich weiss nun wonach ich noch suchen muss wenn was nicht funktioniert! hab davon zwar mal gehört aber irgendwie nie eingesetzt aus welchem Grund auch immer!
Und ich schliesse mich Henri an macht Spass auf einer schön gestalteten Seite zu stöbern und auch noch tolle Infos und interessante Beiträge zu finden
Susanne
Ich nutze immer die Grafik, wenn ich Spezifität erklären muss
http://www.stuffandnonsense.co.uk/archives/images/specificitywars-05v2.jpg
Es ist natürlich einfacher das ganze zu erklären, wenn am Werte wie 1000, 100, 10 und 1 verwendet. Aber ich finde es trotzdem besser es mit so einer Tabelle wie bei SEFLHTML darzustellen. So sieht man sofort, dass 10 Klassen nicht dasselbe für die Selektivität ist, wie 1 ID.
Das mit der Spezifizität ist eigentlich eine relativ einfache Sache, wenn man es kappiert hat. Leider bleibt es trotzdem immer schwierig das im Griff zu behalten, wenn man viel CSS-Code hat. Zum Glück ist es bei CSS (besonders mit Firebug) sehr einfach die Dinge zu testen und zu schauen, was selektiver ist.
Ich finde sonst den Artikel sehr gut gelungen und einfach zu verstehen. Ich wollte auch mal sagen, dass ich den Design deines Blogs sehr gut finde ! Es hilft natürlich auch die Sachen rüberzubringen, wenn die Seite einfach schön ist (und wenn man über CSS schreibt ist es noch desto wichtiger :-) !
Aus eigener Erfahrung mit anderen Webprogrammierern weiß ich, dass sehr viele mit der Spezifität mMn unnötige Verständnisschwierigkeiten haben.
Ganz hilfreich finde ich zu diesem Thema den Beitrag zur Kaskade bei SELFHTML (http://de.selfhtml.org/css/formate/kaskade.htm), der zwar alt, aber immer noch gültig ist.
Mir ist grad noch aufgefallen, das du einen Fehler oben hast: Pseudo-Selektoren haben die gleiche Wertigkeit wie Klassen, wobei es da auch noch Ausnahmen gibt. :not() z.B. ändert nichts an der Spefifität, das war in den Klammer drinsteht schon.
Danke für den Hinweis Sebastian! Ist korrigiert.
Wobei sich jetzt der Fehler fortsetzt. Das letzte Bsp. unter „Verschiedene Beispiele“ stimmt damit auch nicht mehr.
Ohman. Vielen Dank für die Info. Jetzt sollte aber wirklich alles stimmen.
An sich ist glaub ich noch ein Grundproblem hier. Die Ebenen können sich allgemein niemals überschreiben. ID + 10 Klassen (also 100 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10) entspricht nicht gleich 200 sondern 1|10|0
Die ebenen werden also immer getrennt betrachtet:
Inline | ID | Klasse/Pseudo-Selektor | Tag
Gut sind auch die Grafiken am Ende dieses Artikels von Chris Coyier:
http://css-tricks.com/specifics-on-css-specificity/
Ich denke auch, dass Klassen einfach die bessere Wahl sind, um Elemente zu stylen. Fakt ist: Man kann einen Selektor mit einer ID nicht überschreiben, solange man nicht mindestens eine ID in seinem eigenen Selektor hat (habs ausprobiert: http://cdpn.io/qBIjH)
Gerade in Templates, die für die Weiterverwendung gedacht sind, sind IDs der Horror (Ich verfluche dich, Shopware)
Recht haste. Nicht mal wenn man alle Klassen kombiniert. http://codepen.io/anon/pen/KnHwI
to micha:
sorry, aber bei mir ist der hintergrund blau.
habe ich dann nicht den mittels id gesetzten roten background überschrieben?
Puh – das war harter Stoff. Aber äußerst hilfreich und lesenswert – vielen Dank :)
Ich tendiere dazu, auf sämtliche IDs für die Verwendung im CSS zu verzichten (Als Hooks für Javascript etc. natürlich in Ordnung). Ich benutze stattdessen lieber ein-zwei Klassen mehr und habe keine Probleme mit dem specifity-war.
Wie handhabt ihr das?