CSS
Kaskadering och specificitet
Sök…
Anmärkningar
CSS-specificitet avser att främja kodens tydlighet genom att låta en författare definiera några allmänna formateringsregler för en bred uppsättning element och sedan åsidosätta dem för en viss delmängd.
Cascading
Kaskadering och specificitet används tillsammans för att bestämma det slutliga värdet för en CSS-stylingegenskap. De definierar också mekanismerna för att lösa konflikter i CSS-regeluppsättningar.
CSS Laddar order
Stilar läses från följande källor i denna ordning:
- Användaragentens stilark (stilarna som tillhandahålls av webbläsarleverantören)
- Användarstilsblad (Den ytterligare stylingen som en användare har ställt in i sin webbläsare)
- Författarstilsblad (Författare betyder här skaparen av webbsidan / webbplatsen)
- Kanske en eller flera
.css
filer - I
<style>
-elementet i HTML-dokumentet
- Kanske en eller flera
- Inline stilar (I
style
attribut på ett HTML-element)
Webbläsaren kommer att leta upp motsvarande stil (er) när ett element återges.
Hur löses konflikter?
När bara en CSS-regeluppsättning försöker ställa in en stil för ett element, finns det ingen konflikt, och den regeluppsättningen används.
När flera regeluppsättningar hittas med motstridiga inställningar används först Specificty-reglerna och sedan Cascading-reglerna för att bestämma vilken stil som ska användas.
Exempel 1 - Specificitetsregler
.mystyle { color: blue; } /* specificity: 0, 0, 1, 0 */
div { color: red; } /* specificity: 0, 0, 0, 1 */
<div class="mystyle">Hello World</div>
Vilken färg kommer texten att vara? (håll muspekaren för att se svaret)
blå
Först tillämpas specificitetsreglerna och den med den högsta specificiteten "vinner".
Exempel 2 - Kaskadregler med identiska väljare
Extern css-fil
.class {
background: #FFF;
}
Intern css (i HTML-fil)
<style>
.class {
background: #000;
}
<style>
I det här fallet, där du har identiska väljare, sparkar kaskaden in och bestämmer att den sista laddade "vinner".
Exempel 3 - Kaskadregler efter specificitetsregler
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>
Vilken färg kommer bakgrunden att vara?
röd
Efter att ha tillämpat specificitetsreglerna, finns det fortfarande en konflikt mellan blått och rött, så de överlappande reglerna tillämpas ovanpå specificitetsreglerna. Cascading tittar på reglerna för belastning, oavsett om det finns i samma .css
fil eller i samling av stilkällor. Den sista laddade åsidosätter alla tidigare. I detta fall .otherstyle > div
regeln "vinner".
En sista anmärkning
- Väljarens specificitet har alltid företräde.
- Styleskorts ordningsbrott.
- Inline stilar trumpar allt.
Den! Viktiga förklaringen
Den !important
deklarationen används för att åsidosätta den vanliga specificiteten i ett formatmall genom att prioritera en regel högre. Dess användning är: 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 */
}
Att undvika användningen av !important
rekommenderas starkt (såvida det inte är absolut nödvändigt), eftersom det kommer att störa det naturliga flödet av css-regler som kan skapa osäkerhet i din stilmall. Det är också viktigt att notera att när flera !important
deklarationer tillämpas på samma regel på ett visst element, kommer den med högre specificitet att vara den som tillämpas.
Här är några exempel där användning av !important
deklarationer kan motiveras:
- Om dina regler inte bör åsidosättas av någon inline stil med element som är skrivet inuti
style
attribut för HTML-element. - För att ge användaren mer kontroll över webbtillgängligheten, som att öka eller minska storleken på fontstorleken, genom att åsidosätta författerstilen med hjälp av
!important
. - För testning och felsökning med inspektionselement.
Se även:
Beräkna väljarspecificitet
Varje individuell CSS-väljare har sitt eget specificitetsvärde. Varje val i en sekvens ökar sekvensens totala specificitet. Väljarna ingår i en av tre olika specificitetsgrupper: A , B och c . När flera väljarsekvenser väljer ett givet element använder webbläsaren de stilar som används av sekvensen med den högsta totala specificiteten.
Grupp | Bestående av | exempel |
---|---|---|
EN | ID-väljare | #foo |
B | klassväljare attributväljare pseudo-klasser | .bar [title] , [colspan="2"] :hover :nth-child(2) |
c | typväljare pseudo-element | div , li ::before , ::first-letter |
Grupp A är den mest specifika, följt av grupp B , sedan slutligen grupp c .
Universalväljaren ( *
) och kombinationer (som >
och ~
) har ingen specificitet.
Exempel 1: Specificiteten för olika selectorsekvenser
#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 */
Exempel 2: Hur specificitet används av webbläsaren
Föreställ dig följande CSS-implementering:
#foo {
color: blue;
}
.bar {
color: red;
background: black;
}
Här har vi en ID-väljare som deklarerar color
som blå , och en klassväljare som deklarerar color
som röd och background
som svart .
Ett element med ett ID för #foo
och en klass .bar
väljs av båda deklarationerna. ID-väljare har en grupp A- specificitet och klassväljare har en grupp B- specificitet. En ID-väljare uppväger ett antal klassväljare. På grund av detta, color:blue;
från #foo
väljaren och background:black;
från .bar
väljaren kommer att tillämpas på elementet. Den högre specificitet av ID-väljaren gör att webbläsaren för att ignorera .bar
väljarens color
deklaration.
Föreställ dig nu en annan CSS-implementering:
.bar {
color: red;
background: black;
}
.baz {
background: white;
}
Här har vi två klassväljare; den ena deklarerar color
som röd och background
som svart , och den andra förklarar background
som vit .
Ett element med .bar
och .baz
kommer att påverkas av båda dessa deklarationer, men problemet vi har nu är att både .bar
och .baz
har en identisk grupp B- specificitet. CSS kaskade natur löser detta för oss: eftersom .baz
definieras efter .bar
vårt element med den röda color
från .bar
men den vita background
från .baz
.
Exempel 3: Hur man manipulerar specificitet
Den sista utdrag från Exempel 2 ovan kan manipuleras för att säkerställa vår .bar
klass väljarens color
deklaration används i stället för den i .baz
klassväljare.
.bar {} /* a=0, b=1, c=0 */
.baz {} /* a=0, b=1, c=0 */
Det vanligaste sättet att uppnå detta skulle vara att ta reda på vilka andra väljare som kan användas på .bar
. Till exempel, om .bar
klassen bara någonsin tillämpades på span
, kan vi ändra .bar
väljaren till span.bar
. Detta skulle ge den en ny grupp C- specificitet, som skulle åsidosätta .baz
väljarens brist på detta:
span.bar {} /* a=0, b=1, c=1 */
.baz {} /* a=0, b=1, c=0 */
Det är dock inte alltid möjligt att hitta en annan gemensam väljare som delas mellan något element som använder .bar
klassen. På grund av detta tillåter CSS oss att duplicera väljare för att öka specificiteten. I stället för bara .bar
kan vi använda .bar.bar
istället (se grammatiken för väljare, W3C-rekommendation ). Detta väljer fortfarande alla element med en klass .bar
, men har nu dubbelt grupp B- specificitet:
.bar.bar {} /* a=0, b=2, c=0 */
.baz {} /* a=0, b=1, c=0 */
!important
och inline stildeklarationer
Den !important
flagga på en stil uttalande och stilar deklarerats av HTML style
attribut anses ha en större specificitet än någon väljare. Om dessa finns kommer stildeklarationen de påverkar att överstiga andra deklarationer oavsett deras specificitet. Det vill säga om du inte har mer än en deklaration som innehåller en !important
flagga för samma egenskap som gäller för samma element. Sedan kommer normala specificitetsregler att gälla för dessa egenskaper med hänvisning till varandra.
Eftersom de helt åsidosätter specificiteten, är användningen av !important
rynkad i de flesta användningsfall. Man bör använda den så lite som möjligt. För att hålla CSS-koden effektiv och underhållbar på lång sikt är det nästan alltid bättre att öka specificiteten hos den omgivande väljaren än att använda !important
.
Ett av de sällsynta undantagen där !important
inte rynker på, är när man implementerar generiska hjälparklasser som en. .hidden
eller .background-yellow
klass som alltid ska åsidosätta en eller flera egenskaper oavsett var de stöter på. Och även då måste du veta vad du gör. Det sista du vill, när du skriver underhållbar CSS, är att ha !important
flaggor i hela ditt CSS.
En sista anmärkning
En vanlig missuppfattning om CSS-specificitet är att värdena i grupp A , B och c ska kombineras med varandra ( a=1, b=5, c=1
=> 151). Detta är inte fallet. Om detta var fallet skulle 20 av en grupp B- eller c- väljare vara tillräckligt för att åsidosätta en enda grupp A respektive B- väljare. De tre grupperna bör betraktas som individuella nivåer av specificitet. Specificiteten kan inte representeras av ett enda värde.
När du skapar ditt CSS-formatmall ska du bibehålla den lägsta specificiteten som möjligt. Om du behöver göra specificiteten lite högre för att skriva över en annan metod, gör den högre men så låg som möjligt för att göra den högre. Du borde inte behöva ha en väljare som den här:
body.page header.container nav div#main-nav li a {}
Detta gör framtida förändringar svårare och förorenar den css-sidan.
Du kan beräkna specificiteten för din väljare här
Exempel på mer komplex specificitet
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>
Vilka gränser, färger och fontstorlekar kommer texten att vara?
textstorlek:
font-size: 24;
, eftersom#elmnt1
regeluppsättning har den högsta specificiteten för<div>
i fråga, är varje egenskap här inställd.
gräns:
border: 3px dotted red;
.#elmnt1
red
är hämtad från#elmnt1
regeluppsättningen, eftersom den har den högsta specificiteten. De andra egenskaperna för gränsen, gränstjocklek och kantstil är fråndiv
regeluppsättningen.
bakgrundsfärg:
background-color: green;
.background-color
ställs in idiv
,body.mystyle > div.myotherstyle
och.mystyle .myotherstyle
regeluppsättningar. Specificiteterna är (0, 0, 1) vs. (0, 2, 2) vs. (0, 2, 0), så den mellersta "vinner".
Färg:
color: red;
. Färgen ställs in i bådediv
och.mystyle .myotherstyle
regeluppsättningar. Den senare har den högre specificiteten för (0, 2, 0) och "vinner".