Style precedence in CSS: Specificity, Inheritance, and the Cascade

We hebben het allemaal wel eens gehad, de css style die je net hebt aangepast heeft geen effect. Het lijkt wel of de regel compleet niet wordt gezien, en je hebt geen idee waarom. Ten einde raad gebruik je dan maar !important, of een inline stijl, maar laten we eens kijken waar het probleem echt in zit.

De kans is groot dat het probleem te maken heeft met CSS priotiteit (css precedence) 

Een beter begrip van welke CSS stijl prioriteit heeft kan een hoop frustratie schelen, nettere code, en een beter georganiseerde CSS opleveren. Er zijn drie punten die bepalen welke CSS regel gebruitk wordt:

  • Gecalculeerde specificiteit
  • Inheritance (overerving)
  • Cascade (trapsgewijs)

Wanneer je deze 3 regels goed beheerst zal het allemaal een stuk eenvoudiger voor je worden.

 

Berekende specifiteit

Ons voorbeeld heeft een paragraaf met class "bio". In de CSS staan de volgende twee regels:

p {font-size: 12px}
p.bio {font-size: 14px}

Wat zal in dit geval de font-size worden, 12px of 14px? Het zal niet moeilijk zijn om te zien dat het 2e regel verder gespecificeerd is dan de eerste regel, en dus een hogere prioriteit zal hebben. Maar hoe zit dit nu precies in elkaar? Laten we verder kijken naar de exacte regels. 

Als voorbeeld nemen we onderstaande html en css

<div id="sidebar">
    <p class="bio">Stuk mooie tekst</p>
</div>
div p.bio {font-size: 14px}
#sidebar p {font-size: 12px}

De eerste regel lijkt in eerste instantie specifieker, maar het is eigenlijk de tweede regel die de font-size bepaalt. Waarom is dat?

Om dit te kunnen beantwoorden kijken we naar de specificatie regels.

De specificatie wordt berekend aan de hand van 4 componenten (a,b,c,d) welke we in onderstaan voorbeeld uitleggen

  • Element, pseudo element: d = 1 - (0,0,0,1)
  • Class, pseudo class, attribute: c = 1 - (0,0,1,0)
  • Id: b = 1 - (0,1,0,0)
  • Inline stijl: a = 1 - (1,0,0,0)

Hieruit blijkt dus dat een Id specifieker is dan een element of class. Voor het berekenen tell je alle elementen, classes, id en inline stijlen op voor de a,b,c,d reeks. Let dan op dat 0,0,1,0 specifieker is dan 0,0,0,15. Hieronder nog een paar voorbeelden voor de duidelijkheid.

  • p: 1 element = (0,0,0,1)
  • div: 1 element = (0,0,0,1)
  • #sidebar: 1 id = (0,1,0,0)
  • div#sidebar: 1 element en 1 id = (0,1,0,1)
  • div#sidebar p: 2 elementen en 1 id = (0,1,0,2)
  • div#sidebar p.bio: 2 elementen, 1 class en 1 id = (0,1,1,2)

Kijken we nu nogmaals naar het voorbeeld

div p.bio {font-size: 14px} - (0,0,1,2)

#sidebar p {font-size: 12px) - (0,1,0,1)

De tweede regel is specifieker en is dus bepalend.

Nog een opmerking voordat we naar het tweede punt gaan. Het gebruik van !importance overruled de berekening, en is dus altijd bepalend. Dit wordt nog steeds veel gebruikt als "hack", maar zou niet nodig zijn als je de regels goed toepast. Hieronder een voorbeel zodat regel 1 toch bepalend is ipv regel 2.

div p.bio {font-size: 14px !important}

#sidebar p {font-size: 12px}

 

Inheritance

Het idee achter inheritance is eigenlijk heel eenvoudig. Elementen overerven de stijlen van hun parent container. Stel je zet de body tag color red, dan zal alle tekst in de body de kleur rood krijgen, mits niet anders gespecificeerd. 

Dit geld echter niet voor alle eigenschappen, bijvoorbeeld de eigenschappen margin en padding overerven niet de stijl van hun parent. Dus als je de margin en padding van een div zet, zullen deze niet worden overgenomen door een paragraaf die je in de div hebt gedefineerd. De paragraaf zal de door de browser gefefineerde margin en padding waarden gebruiken. 

Het is mogelijk om ook voor margin en padding overerving toe te passen.

p {margin: inherit; padding: inherit}

 

The Cascade

De cascade werkt als volgt

  1. Zoek alle CSS declaraties voor het element in kwestie
  2. Sorteer op herkomst en zwaarte. Met herkomst bedoelen we waar de CSS gedeclareerd wordt (author styles, user styles en browser defaults) en zwaarte is de volgorder vanbelangrijkheid. Belangrijkste eerst:
    1. !important
    2. author style
    3. user style
    4. browser default style
  3. Bereken specifiteit
  4. Indien 2 regels gelijke belangrijkheid hebben dan heeft de laatst gedefineerde regel de voorkeur. Bovendien wordt de embedded CSS in de HTML altijd geladen NA de externe stylesheets.

Meestal zal punt 3 de meeste aandacht vragen.