CSS
Cascading en specificiteit
Zoeken…
Opmerkingen
CSS-specificiteit is bedoeld om beknoptheid van de code te bevorderen door een auteur toe te staan enkele algemene opmaakregels voor een brede set elementen te definiëren en deze vervolgens voor een bepaalde subset te overschrijven.
Cascading
Cascading en specificiteit worden samen gebruikt om de uiteindelijke waarde van een CSS-stijleigenschap te bepalen. Ze definiëren ook de mechanismen voor het oplossen van conflicten in CSS-regelsets.
CSS Laadvolgorde
Stijlen worden gelezen uit de volgende bronnen, in deze volgorde:
- User Agent-stylesheet (de stijlen die door de browserleverancier worden geleverd)
- Gebruikersstijlblad (de extra stijl die een gebruiker in zijn / haar browser heeft ingesteld)
- Stylesheet voor auteur (auteur betekent hier de maker van de webpagina / website)
- Misschien een of meer
.css
bestanden - In het element
<style>
van het HTML-document
- Misschien een of meer
- Inline-stijlen (in het
style
op een HTML-element)
De browser zal de overeenkomstige stijl (stijlen) opzoeken bij het renderen van een element.
Hoe worden conflicten opgelost?
Wanneer slechts één CSS-regelset een stijl voor een element probeert in te stellen, is er geen conflict en wordt die regelset gebruikt.
Wanneer meerdere regelsets worden gevonden met conflicterende instellingen, worden eerst de Specificty-regels en vervolgens de Cascading-regels gebruikt om te bepalen welke stijl moet worden gebruikt.
Voorbeeld 1 - Specificiteitsregels
.mystyle { color: blue; } /* specificity: 0, 0, 1, 0 */
div { color: red; } /* specificity: 0, 0, 0, 1 */
<div class="mystyle">Hello World</div>
Welke kleur heeft de tekst? (beweeg om het antwoord te zien)
blauw
Eerst worden de specificiteitsregels toegepast, en degene met de hoogste specificiteit "wint".
Voorbeeld 2 - Cascaderegels met identieke selectors
Extern css-bestand
.class {
background: #FFF;
}
Interne CSS (in HTML-bestand)
<style>
.class {
background: #000;
}
<style>
In dit geval, wanneer u identieke selectors heeft, begint de cascade en bepaalt dat de laatst geladen "wint".
Voorbeeld 3 - Cascade-regels na specificiteitsregels
body > .mystyle { background-color: blue; } /* specificity: 0, 0, 1, 1 */
.otherstyle > div { background-color: red; } /* specificity: 0, 0, 1, 1 */
<body class="otherstyle">
<div class="mystyle">Hello World</div>
</body>
Welke kleur heeft de achtergrond?
rood
Na het toepassen van de specificiteitsregels is er nog steeds een conflict tussen blauw en rood, dus de trapsgewijze regels worden bovenop de specificiteitsregels toegepast. Cascading kijkt naar de laadvolgorde van de regels, of dit nu in hetzelfde .css
bestand is of in de verzameling stijlbronnen. De laatst geladen vervangt alle eerdere. In dit geval "wint" de .otherstyle > div
regel.
Een laatste opmerking
- De specificiteit van de selector heeft altijd voorrang.
- Stylesheet order verbreekt banden.
- Inline stijlen overtreffen alles.
De! Belangrijke verklaring
De !important
verklaring wordt gebruikt om de gebruikelijke specificiteit in een stylesheet te overschrijven door een regel een hogere prioriteit te geven. Het gebruik ervan is: property : value !important;
#mydiv {
font-weight: bold !important; /* This property won't be overridden
by the rule below */
}
#outerdiv #mydiv {
font-weight: normal; /* #mydiv font-weight won't be set to normal
even if it has a higher specificity because
of the !important declaration above */
}
Het gebruik van !important
vermijden wordt sterk aanbevolen (tenzij absoluut noodzakelijk), omdat het de natuurlijke stroom van CSS-regels verstoort die onzekerheid in uw stijlblad kan veroorzaken. Het is ook belangrijk op te merken dat wanneer meerdere !important
verklaringen worden toegepast op dezelfde regel voor een bepaald element, degene met de hogere specificiteit de toegepaste ona zal zijn.
Hier zijn enkele voorbeelden waar het gebruik van !important
verklaringen gerechtvaardigd kan zijn:
- Als uw regels niet moeten worden overschreven door een inline stijl van het element die is geschreven in het
style
van het html-element. - Om de gebruiker meer controle te geven over de webtoegankelijkheid, zoals het vergroten of verkleinen van de lettergrootte, door de auteursstijl te overschrijven met
!important
. - Voor testen en debuggen met behulp van inspecteerelement.
Zie ook:
Specificeren van selector specificiteit
Elke afzonderlijke CSS-selector heeft zijn eigen specificiteitswaarde. Elke selector in een reeks verhoogt de algehele specificiteit van de reeks. Selectors vallen in een van de drie verschillende specificiteitsgroepen: A , B en c . Wanneer meerdere selectiereeksen een bepaald element selecteren, gebruikt de browser de stijlen die worden toegepast door de reeks met de hoogste algemene specificiteit.
Groep | Bestaande uit | Voorbeelden |
---|---|---|
EEN | id selectors | #foo |
B | klassekiezers kenmerkkiezers pseudo-classes | .bar [title] , [colspan="2"] :hover :nth-child(2) |
c | type selectors pseudo-elementen | div , li ::before , ::first-letter |
Groep A is de meest specifieke, gevolgd door Groep B , en ten slotte Groep c .
De universele selector ( *
) en combinators (zoals >
en ~
) hebben geen specificiteit.
Voorbeeld 1: specificiteit van verschillende selectorsequenties
#foo #baz {} /* a=2, b=0, c=0 */
#foo.bar {} /* a=1, b=1, c=0 */
#foo {} /* a=1, b=0, c=0 */
.bar:hover {} /* a=0, b=2, c=0 */
div.bar {} /* a=0, b=1, c=1 */
:hover {} /* a=0, b=1, c=0 */
[title] {} /* a=0, b=1, c=0 */
.bar {} /* a=0, b=1, c=0 */
div ul + li {} /* a=0, b=0, c=3 */
p::after {} /* a=0, b=0, c=2 */
*::before {} /* a=0, b=0, c=1 */
::before {} /* a=0, b=0, c=1 */
div {} /* a=0, b=0, c=1 */
* {} /* a=0, b=0, c=0 */
Voorbeeld 2: hoe specificiteit wordt gebruikt door de browser
Stelt u zich de volgende CSS-implementatie voor:
#foo {
color: blue;
}
.bar {
color: red;
background: black;
}
Hier hebben we een ID-selector die de color
blauw aangeeft, en een klassenkiezer die de color
rood en de background
zwart aangeeft.
Een element met een ID van #foo
en een klasse van .bar
wordt door beide verklaringen geselecteerd. ID-selectors hebben een Group A- specificiteit en class-selectors hebben een Group B- specificiteit. Een ID-selector weegt zwaarder dan een willekeurig aantal klassekiezers. Vanwege dit, color:blue;
van de #foo
selector en de background:black;
van de .bar
selector wordt op het element toegepast. De hogere specificiteit van de ID selector zal de browser om de negeren veroorzaken .bar
selector color
verklaring.
Stel je nu een andere CSS-implementatie voor:
.bar {
color: red;
background: black;
}
.baz {
background: white;
}
Hier hebben we twee klassekiezers; waarvan één color
rood en background
zwart aangeeft en de andere background
wit .
Een element met zowel de .bar
als .baz
klassen wordt beïnvloed door beide verklaringen, maar het probleem dat we nu hebben is dat zowel .bar
als .baz
een identieke Groep B- specificiteit hebben. De trapsgewijze aard van CSS lost dit voor ons op: aangezien .baz
wordt gedefinieerd na .bar
, eindigt ons element met de rode color
van .bar
maar de witte background
van .baz
.
Voorbeeld 3: specificiteit manipuleren
Het laatste fragment uit Voorbeeld 2 hierboven kunnen worden gemanipuleerd om ons zorgen .bar
class selector color
verklaring wordt gebruikt in plaats van die van de .baz
klasseselector.
.bar {} /* a=0, b=1, c=0 */
.baz {} /* a=0, b=1, c=0 */
De meest gebruikelijke manier om dit te bereiken is om erachter te komen welke andere selectors kunnen worden toegepast op de .bar
selectorreeks. Als de .bar
klasse bijvoorbeeld alleen ooit op span
elementen werd toegepast, konden we de .bar
selector wijzigen in span.bar
. Dit zou het een nieuwe Groep C- specificiteit geven, die het gebrek daaraan van de .baz
selector .baz
zou doen:
span.bar {} /* a=0, b=1, c=1 */
.baz {} /* a=0, b=1, c=0 */
Het is echter niet altijd mogelijk om een andere gemeenschappelijke selector te vinden die wordt gedeeld tussen elk element dat de .bar
klasse gebruikt. Daarom stelt CSS ons in staat om selectors te dupliceren om de specificiteit te vergroten. In plaats van alleen .bar
kunnen we in plaats daarvan .bar.bar
gebruiken (zie De grammatica van selectors, W3C-aanbeveling ). Dit selecteert nog steeds elk element met een klasse van .bar
, maar heeft nu het dubbele van de Groep B- specificiteit:
.bar.bar {} /* a=0, b=2, c=0 */
.baz {} /* a=0, b=1, c=0 */
!important
en inline-stijlverklaringen
De !important
vlag op een stijldeclaratie en stijlen gedeclareerd door het HTML- style
worden beschouwd als een grotere specificiteit dan welke selector ook. Als deze bestaan, overschrijft de stijlverklaring waarop ze van invloed zijn andere verklaringen, ongeacht hun specificiteit. Dat wil zeggen, tenzij u meer dan één verklaring hebt die een !important
vlag voor dezelfde eigenschap bevat die op hetzelfde element van toepassing is. Dan zullen normale specificiteitsregels op die eigenschappen van toepassing zijn met betrekking tot elkaar.
Omdat ze specificiteit volledig teniet doen, wordt het gebruik van !important
in de meeste gevallen afgekeurd. Men moet het zo min mogelijk gebruiken. Om CSS-code op de lange termijn efficiënt en onderhoudbaar te houden, is het bijna altijd beter om de specificiteit van de omringende selector te vergroten dan te gebruiken !important
.
Een van die zeldzame uitzonderingen waar !important
niet wordt afgekeurd, is bij het implementeren van generieke .hidden
zoals een .hidden
of .background-yellow
klasse waarvan wordt verondersteld dat ze altijd een of meer eigenschappen overschrijven, waar ze zich ook voordoen. En zelfs dan moet je weten wat je doet. Het laatste wat u wilt, bij het schrijven van onderhoudbare CSS, is !important
vlaggen in uw CSS.
Een laatste opmerking
Een veel voorkomende misvatting over CSS-specificiteit is dat de waarden van Groep A , B en c met elkaar moeten worden gecombineerd ( a=1, b=5, c=1
=> 151). Dit is niet het geval. Als dit het geval zou zijn, zou het hebben van 20 van een groep B of c selector voldoende zijn om een enkele groep A of B selector te vervangen. De drie groepen moeten worden beschouwd als individuele specificiteitsniveaus. Specificiteit kan niet worden vertegenwoordigd door een enkele waarde.
Wanneer u uw CSS-stylesheet maakt, moet u de laagst mogelijke specificiteit behouden. Als u de specificiteit iets hoger wilt maken om een andere methode te overschrijven, maak deze dan hoger maar zo laag mogelijk om deze hoger te maken. U zou geen selector als deze moeten hebben:
body.page header.container nav div#main-nav li a {}
Dit maakt toekomstige wijzigingen moeilijker en vervuilt die css-pagina.
U kunt de specificiteit van uw selector berekenen hier
Complexer specificiteitsvoorbeeld
div {
font-size: 7px;
border: 3px dotted pink;
background-color: yellow;
color: purple;
}
body.mystyle > div.myotherstyle {
font-size: 11px;
background-color: green;
}
#elmnt1 {
font-size: 24px;
border-color: red;
}
.mystyle .myotherstyle {
font-size: 16px;
background-color: black;
color: red;
}
<body class="mystyle">
<div id="elmnt1" class="myotherstyle">
Hello, world!
</div>
</body>
Welke randen, kleuren en lettergroottes heeft de tekst?
lettertypegrootte:
font-size: 24;
, aangezien#elmnt1
regelset de hoogste specificiteit heeft voor de<div>
in kwestie, wordt elke eigenschap hier ingesteld.
grens:
border: 3px dotted red;
. De randkleurred
is ontleend aan#elmnt1
regelset, omdat deze de hoogste specificiteit heeft. De andere eigenschappen van de rand, randdikte en randstijl komen uit dediv
regelset.
Achtergrond kleur:
background-color: green;
. Debackground-color
wordt ingesteld in debody.mystyle > div.myotherstyle
div
,body.mystyle > div.myotherstyle
en.mystyle .myotherstyle
. De specificiteiten zijn (0, 0, 1) versus (0, 2, 2) versus (0, 2, 0), dus de middelste "wint".
kleur:
color: red;
. De kleur wordt ingesteld in zowel dediv
en.mystyle .myotherstyle
regel sets. De laatste heeft de hogere specificiteit van (0, 2, 0) en "overwinningen".