CSS: Specificity Wars

Iedereen die met CSS bezig weet dat als je 2 specificaties schrijft, de 2de regel voorrang heeft op de 1ste bij de huidige moderne browsers, wat als ik je nou eens zou zeggen dat opeens niet meer waar was ?

Dit is de officiële vertaling van de CSS: Specificity Wars van Andy Clarke , en er is vriendelijk toelating gegeven aan Gigadesign.be om deze te publiceren.
Waarvoor dank.

Het origineel is in de “ik”-vorm geschreven, dus ook de vertaling waardoor het niet mijzelf betrefd, maar wel Andy Clarke.

“Join me, and together we can rule the galaxy as father and geeks!”

Andy’s inspiratie & motivatie voor dit artikel kwam erdoor toen dat Molly en Aaron hem uitlegden hoe de specificiteit van CSS selectors wordt berekend, dan op een dag bij het maken van een Xhtml/Css website voor een nieuw project hij ontdekte dat 2 selectors een ander resultaat hadden dan dat hij verwachte.

The Dark Side

Het was een simpel probleem, hoe zorg je ervoor dat je een .png afbeelding serveert voor browsers die transparentie ondersteunen, en een .gif afbeelding voor oudere browsers, die dit niet ondersteunen, zonder enige hulp van hacks. Hier is de structuur:

<div id="nav-supp">
<p><a id="a-02" href="#webstandards-org">Top</a></p>
<!-- etc. -->
</div>

En hier de CSS waar ik vanuit ging:

a#a-02 { background-image : url(n.gif); }
a[id="a-02"] { background-image : url(n.png); }

Ik ging ervan uit dat een moderne browser alle 2 regels zou zien en zou uitvoeren (waarbij de 2de regel voorrang heeft op de 1ste) en dat een oudere browser welke de atribuut selector niet begrijpt enkel de 1ste regel zou zien en uitvoeren en de 2de regel compleet zou negeren. Ik was fout. De moderne browsers gaven niet, de voor hun bestemde .png afbeelding weer zoals ik verwachte.
De reden? Een standaard id selector wint van een atribuut selector volgens de regels van de hierarchie. Verdomme! Ik weet, ik zou de specificaties moeten gelezen hebben, maar hoe dan ook, dit plezier is mij ontgaan. Als ik dit gedaan zou hebben, zou ik geleerd hebben dat:

Id selectors hebben een hogere specificatie hebben dan atribuut selectors. Bijvoorbeeld, in Html, de selector #p123 is meer specifiek dan [id=123] volgens de regels ven de hierarchie.

Sith Lords

Een kleine Google-speurtocht leverde een eerder saaie verhandeling op over het onderwerp “selector specificiteit” (Bronnen onderaan)

Eerst, kijken we eens terug wat Lord Elasticus (Patrick Griffiths) schreef over het onderwerp specificiteit (met 1 of 2 kleine aanpassingen om het met het voorbeeld te laten kloppen).

  • Je geeft elke id selector een waarde van 100, elke class selector (”.whatever”) een waarde van 10 en elke Html selector (”whatever”) een waarde van 1. Dan tel je alles op en wonder over wonder, je hebt de specifieke waarde.
    • p heeft een specifieke waarde van 1 (1 Html selector)
    • div p heeft een specifieke waarde van 2 (2 Html selectors: 1+1)
    • .sith heeft een specifieke waarde van 10 (1 class selector)
    • div p.sith heeft een specifieke waarde van 12 (2 Html selectors en 1 class selector: 1+1+10)
    • #sith heeft een specifieke waarde van 100 (1 id selector)
    • body #darkside .sith p heeft een specifieke waarde van 112 (Html selector, id selector, class selector, Html selector: 1+100+10+1 )
  • In de voorbeelden die wij gebruikten, div p.sith (met een specifieke waarde van 12) zou winnen van een div p (met een specifieke waarde van 2), en body #darkside .sith p zou van ze allemaal winnen, om het even in welke volgorde.

Darth (Gez) Lemon quotes the W3C.

  • De selectors specificiteit wordt berekend op volgende manier:
    • tel het aantal id atributen in de selector (=a)
    • tel het aantal andere atributen en pseudo-classes in de selector (=b)
    • tel het aantal elementen in de selector (=c)
    • negeer pseudo-elementen
  • Het aaneenschakelen van de drie aantallen a-b-c (in een aantalsysteem met een grote basis) geeft de specificiteit.

Teveel! Voor mij, de W3C is echt een galaxy far, far away!

Is het mogelijk om deze krachten te leren?

Wiskunde is nooit mijn sterkste kant geweest, dus om het mij gemakkelijker te maken de specificaties te berekenen maakte ik een grafiek gebaseerd op de volgende specificiteit’s (of Sith krachten) waarden (Ed zegt: “Negeer inline styles en !important”).


element selector

class selector

id selector
Sith macht: 0,0,1
(1)
Sith macht: 0,1,0
(10)
Sith macht: 1,0,0
(100)

Elk karakter (selector) wordt zijn eigen Sith-macht gegeven (specificiteitwaarde) afhankelijk van hoe krachtig zij op de manieren van de “Dark Side” zijn. Een “Stormtrooper” is minder krachtig dan “Vader” die op zijn beurt weer minder krachtig dan de “Emperor” is.

klik voor vergroting
CSS: Specificity Wars: (jpg, 142Kb)
(Updated. Bedankt aan Molly en Eric voor de uitleg).

Bronnen

  1. W3C
  2. CSS - Specificity - HTML Dog
  3. Juicy Studio: Selector Specificity
  4. HTML Help: CSS Structure and Rules
  5. Molly: CSS2 and CSS2.1 specificity clarified
  6. Meyerweb: Link Specificity

Do not underestimate the power of the Dark Side

Ongeloofelijk, Star Wars hielp mij CSS beter te begrijpen, Sluit je bij mij aan, en samen kunnen wij het universum regeren als vader en geeks!