Specificiteit in CSS, zo werkt het

Specificiteit in CSS is een belangrijke oorzaak van selectors die niet doen wat jij wilt. Specificiteit gaat over hoe zwaar een selector telt en of een concurrerende selector sterk genoeg is om hem te overschrijven. De oplossing begint met begrijpen hoe specificiteit werkt. Een goede tweede is: houd de specificiteit van je selectors zo laag als kan en zo hoog als nodig is.

Specificiteit speelt alleen een rol als je CSS-declaraties uit gelijkwaardige bronnen komen. In jouw geval, als auteur van het webdocument, zijn gelijkwaardige bronnen je externe stylesheets en de declaraties in een element style in de head van je webpagina. Opmaak in een attribuut style bij een HTML-element is geen gelijkwaardige bron, want die heeft juist een heel hoge specificiteit.

Test je kennis

Een voorbeeld. Welke kleur krijgt de kop h2?

<h2 class="tussenkop" style="color: purple">
Welke kleur krijg ik?</h2>
.tussenkop { 
  color: green 
}
h2 { 
  color: red 
}

Het attribuut style heeft een hogere specificiteit dan een klasse en een typeselector. Daarom is de kop paars.

Andere situatie. Welke kleur krijgt de kop h2?

<h2 class="tussenkop">
Welke kleur krijg ik?</h2>
.tussenkop { 
  color: green 
}
h2 { 
  color: red 
}

De kop is groen, want de klasseselector is specifieker dan de typeselector.

Specificiteit berekenen

Voor het berekenen van specificiteit zijn de selectors verdeeld in groepen – de universele selector telt niet mee. De groepen zijn:

  • het attribuut style bij een element (inline opmaak)
  • het attribuut id
  • pseudoklassen en attributen (waaronder class)
  • typeselectors en pseudo-elementen

Staat in je HTML bij een element het attribuut style, dan ben je gauw klaar, want die gaat boven alle andere selectors. Staat de opmaak in stylesheets, dan ga je rekenen:

  • begin met 0
  • geef elke id 100 punten
  • geef elke (pseudo)klasse/attribuut 10 punten
  • geef elke typeselector 1 punt.

De selector met het hoogste totaal wint.

Een paar voorbeelden:

#main-content article.featured h2 + p {}

Specificiteit 113: 100 + 1 + 10 + 1 + 1

#main-content article h2 + p {}

Specificiteit 103: 100 + 1 + 1 + 1

article.featured h2 + p {}

Specificiteit 13: 1 + 10 + 1 + 1

Een lijst met een selectorprobleem

Je hebt bijvoorbeeld een lijst van dingen die je leuk vindt:

<ul id="leuke-dingen">
  <li>leukst</li>
  <li>leuker</li>
  <li>leuk</li>
</ul>

Het ding dat je het leukst vindt, wil je laten opvallen en daarom geef je het een klasse:

<ul id="leuke-dingen">
  <li class="leukst">leukst</li>
  <li>leuker</li>
  <li>leuk</li>
</ul>

Je schrijft een declaratie voor alle lijstitems en een voor het leukste item:

#leuke-dingen li {
  color: darkgreen;
  font-weight: normal;
}
li.leukst {
  color: orange;
  font-weight: bold;
}

Je bekijkt het resultaat in de browser en je ziet… dat alle items er hetzelfde uitzien, groen en niet vet. De reden: de klasse verliest het van de id. De specificiteit is 101 tegen 11.

Oplossingen voor specificiteit

Oplossing 1: herhaal de eerste selector en voeg de klasse toe. De selector met de klasse heeft nu een hogere specificiteit (101 tegen 111).

#leuke-dingen li { ... }
#leuke-dingen li.leukst { ... }

Oplossing 2: gebruik de id als attribuutselector. De selectors hebben nu dezelfde specificiteit (11). In dat geval telt de laatste declaratie (de volgorderegel), dus als je de volgorde van de selectors omdraait werkt het niet.

[id="leuke-dingen"] li { ... }
li.leukst { ... }

Oplossing 3: gebruik moderne pseudoklassen zoals :not, :where en :is(). Met :where() telt de id niet meer mee en wordt de specificiteit 1 tegenover 11:

:where(#leuke-dingen) li { ... }
li.leukst { ... }

Oplossing 3 is mooier dan 2. Een id als attribuutselector  is toch een hack, terwijl :where() wordt gebruikt zoals het is bedoeld.
Oplossing 4: je gebruikt geen id maar een klasse. Als je die mogelijkheid hebt scheelt dat veel problemen. Je selector lijkt op oplossing 1 (nu met specificiteit 11 tegenover 21):

.leuke-dingen li { ... }
.leuke-dingen li.leukst { ... }

of je doet dit:

.leuke-dingen li { ... }
li.leukst { ... }

In dit laatste voorbeeld is de volgorde weer belangrijk, want beide selectors hebben specificiteit 11 en de laatste telt. Daarmee volg je gelijk de aanbevolen werkwijze om selectors te schrijven van algemeen naar uitzondering. Eerst de hele lijst, dan het afwijkende item.

Eigenschappen overschrijven met !important

Lukt het niet om een selector te overschrijven met een specifiekere selector, en kun je die selector ook niet minder specifiek maken, dan kun je er nog overheen door aan de eigenschap het sleutelwoord !important toe te voegen.

li.leukst {
  color: orange !important;
  font-weight: bold !important;
}

Specificiteit doet er niet meer toe, !important gaat boven alles. Dat is gelijk ook het probleem. Je komt er alleen nog met andere !important-regels overheen. Het algemene advies is daarom: vermijd als het even kan het gebruik ervan. Dankzij nieuwe, moderne selectors zoals :where() is dat ook een stuk eenvoudiger geworden. Lees daar meer over in het artikel Leer werken met nieuwe pseudoklassen van CSS.


Goed om te zien dat het artikel je tot het einde toe heeft kunnen interesseren. De meeste artikelen op dit blog worden geschreven door de auteurs van
uitgeverij Van Duuren Media.
Ben je geïnteresseerd in verdere verdieping of meer praktische toepassingen? Klik op onderstaande banner voor het meest actuele overzicht.

Geef een reactie

Deze site gebruikt Akismet om spam te verminderen. Bekijk hoe je reactie-gegevens worden verwerkt.