aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Frontend & UI

CSS Specificity: welke regel wint?

Je stelt vanuit drie verschillende plekken een kleur in op een element, maar de browser kiest juist de kleur die je niet wilde. Hier komt CSS specificity om de hoek kijken: het is het prioriteitssysteem dat bepaalt welke regel wint wanneer meerdere declaraties hetzelfde element targeten. Zodra je specificity begrijpt, verdwijnen de uren die je verloor aan "waarom werkt deze stijl niet?". In plaats van willekeurig !important rond te strooien, zie je precies waarom een regel wel of niet wordt toegepast.

Wat is de cascade en waar past specificity?

Het "Cascading" in CSS is het proces waarmee de browser conflicterende regels ordent. Om een winnaar te kiezen doorloopt hij deze stappen in volgorde:

  • Oorsprong en belang: waar de stijl vandaan komt (browser-standaarden, gebruikersstijlen, auteursstijlen) en of hij !important draagt.
  • Specificity: hoe "specifiek" de selector is — onze hoofdfocus hier.
  • Bronvolgorde: als al het andere gelijk is, wint de regel die als laatste in het document staat.

Specificity beslist dus niet alleen; het is één trede van de cascade. Maar in het dagelijks werk is het de trede die mensen het meest verwart en de meeste conflicten veroorzaakt.

Hoe specificity wordt berekend: een waarde in drie delen

Stel je voor dat elke selector een waarde met drie componenten krijgt, vaak geschreven als een triplet (a, b, c):

  • a — ID-selectors: elke ID zoals #header scoort één punt.
  • b — classes, attributen en pseudo-classes: elke .btn, [type="text"], :hover scoort één punt.
  • c — elementen en pseudo-elementen: elke div, a, ::before scoort één punt.

De vergelijking loopt van links naar rechts: eerst a, dan b bij gelijkstand, dan c. Een paar voorbeelden:

/* (0,0,1) — enkel element */
p { color: black; }

/* (0,1,1) — één class + één element */
p.intro { color: blue; }

/* (1,0,0) — enkele ID */
#main { color: green; }

/* (1,1,1) — ID + class + element */
#main p.intro { color: red; }

Als ze allemaal hetzelfde <p class="intro"> targeten, wint #main p.intro met de hoogste waarde, dus de kleur is rood. Eén cruciaal detail: de waarden worden niet in basis tien opgeteld. Elf classes (0,11,0) verslaan nooit één enkele ID (1,0,0). Eén enkele 1 in de a-kolom overtreft elk aantal punten in de b-kolom.

Selectors die niets scoren, en speciale gevallen

Sommige dingen dragen niets bij aan de specificity:

  • De universele selector * en de combinators (>, +, ~, witruimte) voegen niets toe.
  • :where() levert altijd nul specificity op, wat je er ook in zet. Ideaal om "zachte" standaarden te schrijven die makkelijk te overschrijven zijn.
  • :is() en :not() voegen zelf niets toe, maar nemen de score van de meest specifieke selector erin. Zo telt :is(#a, .b) net zo zwaar als een ID.
/* een regel met :where() heeft nul specificity */
:where(.card) a { color: teal; }

/* zelfs een enkele element-selector verslaat hem (0,0,2 > 0,0,1) */
.card a { color: orange; }

!important en inline-stijlen: de volgordebrekers

Twee dingen vallen buiten de normale specificity-berekening. Het eerste is inline-stijl, het style-attribuut, dat sterker is dan elke selector-gebaseerde regel (conceptueel een vierde, meest linkse kolom). Het tweede is !important: het toevoegen aan een declaratie verplaatst die declaratie naar een aparte, hogere laag.

<p id="x" style="color: green">Hallo</p>

#x { color: red; }              /* inline wint → groen */
#x { color: blue !important; }  /* !important verslaat zelfs inline → blauw */

Wanneer twee !important-declaraties botsen, beslissen normale specificity en bronvolgorde opnieuw tussen hen. Het praktische advies is helder: behandel !important als laatste redmiddel. Zodra je het begint te gebruiken, vereist het overschrijven ervan weer een !important, en verandert je stylesheet in een escalatieoorlog.

Specificity-oorlogen in de praktijk vermijden

Het doel is werken met lage en consistente specificity:

  • Gebruik classes in plaats van ID's: bij het stylen brengen ID's een onnodig hoge score. Houd je selectors class-gebaseerd.
  • Houd selectors ondiep: in plaats van .nav ul li a, target direct één class zoals .nav-link.
  • Gebruik cascade layers: met @layer stel je de laag-prioriteit expliciet in; een latere laag verslaat een eerdere, los van specificity.
  • Gebruik :where() voor zachte standaarden zodat gebruikers van een component stijlen makkelijk kunnen overschrijven.

Open het "Styles"-paneel in de DevTools van je browser: doorgestreepte declaraties tonen meteen welke regel werd overschreven en welke won. Dat paneel lezen in plaats van gokken is de snelste manier om specificity eigen te maken.

Veelgestelde vragen

Wat gebeurt er bij gelijke specificity?

Als oorsprong, belang en specificity allemaal gelijk zijn, beslist de bronvolgorde: de regel die als laatste in de CSS is gedefinieerd, wint. Daarom is het vaak genoeg om een override na de bestaande regel te plaatsen.

Wint !important altijd?

Onder auteursstijlen verslaat het bijna altijd normale declaraties. Maar als een andere !important-declaratie een hogere specificity heeft of later komt, wint die. Bouw waar mogelijk een structuur die !important helemaal niet nodig heeft.

Wat is het verschil tussen :is() en :where()?

Beide groeperen een selectorlijst en matchen dezelfde elementen. Het verschil zit in de specificity: :is() neemt de score van de meest specifieke selector erin, terwijl :where() altijd nul oplevert.

Als je stijlconflicten uit de hand zijn gelopen en je CSS een onhoudbare stapel !important is geworden, kan ik je helpen de architectuur naar een class-gebaseerde, gelaagde structuur te verhuizen. Wil je een project bespreken, neem dan contact met me op.

Bu kategorideki tüm yazılar →

Devamı için