CSS-specificitet är ett ämne som många nya frontend kodare undviker så länge som möjligt. Det låter komplicerat, det finns alla dessa regler, du kan till och med behöva göra lite matte! Hur lame är det?
I slutändan kan du bara undvika det så länge. Specificitet är ett viktigt begrepp som du behöver förstå för att vara en effektiv utvecklare. Idag går jag igenom begreppen specificitet på ett enkelt och lättförståeligt sätt. Det är lättare än du tror!
Core Concept of Specificity
Specificitet är ett roligt ord, allt från början kommunicerar den tanken att detta kommer att bli komplicerat. Lyckligtvis är barken större än sitt bett. Det finns ingen anledning att du inte kan välja mest av dessa saker på några minuter eller mindre.
Att bryta den praktiska tillämpningen av specificitet ner i någonting som någon kan bryta sig om, låt oss använda en välbekant metafor.
Vem skulle vinna i en kamp?
När du var barn var världen en mycket kallare plats. Om du fick möjlighet att ställa en och en fråga till en allvetande enhet, skulle du inte ha funderat över meningen med livet eller vågat fram en fråga om huruvida världsfred är uppnådd, bara en sak skulle betyda. Om Batman och Spiderman kom i en kamp, vem skulle vinna?
ScrewAttack skriver stora bitar avsedda för pitting hjältar mot varandra.
Det finns denna medfödda nyfikenhet hos barn att ständigt jämföra saker och fråga vilken är bättre. När vi blir äldre växlar gråtoner svart och vitt och vi förlorar den här tendensen (våra nördar är givetvis ett undantag). För att förstå CSS-specificitet bör du återgå till barndomen. När du ges två liknande väljare, fråga dig själv,? Vem skulle vinna i en kamp ?? Svaret kan vara kritiskt för hur du kodar.
För att se hur det fungerar, låt oss kasta några väljare mot varandra och se vad som händer.
Och det sista kommer att vara först
För vår första kamp, låt oss gropa två väsentligen identiska väljare mot varandra. Hur vet vi vilken väljare som vinner?
Prata om klass krigföring. Puns åt sidan, föreställ dig att vi hade följande inställning på vår hemsida:
Här har vi en lika matchuppgift. Båda klasserna appliceras på samma div med inga andra komplexiteter för att muck upp exemplet. Låt oss släppa ut dem och se vem som vinner?
Lådan är röd! Det betyder att? .Box? klass vann. Men varför? Du vet förmodligen redan svaret rätt? Det kom senast. Byt väljarna och vi ser det motsatta resultatet:
Här är torget blått eftersom den. Blåa? klassen kom sist och tvingade? klass.
Klass ändrar inte vem du är
Det sista slaget var inte särskilt intressant. Motståndarna var för lika matchade och resultatet var uppenbart. Vi har inte ens skrapat ytan av specificitet ännu. Ändå var det en nödvändig grund som krävdes.
Nu dyker vi in i en kamp som är lite mer saftig: ID vs Klass.
Vår inställning här är ungefär som förra gången, bara i stället för två klasser, vi har en klass och ett ID:
Med tanke på den regel som vi lärde oss förra gången kan du förutse att klassen skulle vinna i detta scenario. Låt oss se om det visar sig sant.
En upprörd! Trots att klassen kom efter ID, förlorade den fortfarande. Detta indikerar att ID: er på något sätt starkare än klasser i striden om specificitet.
Pseudo Death Match
Innan vi hoppar in för att se hur allt detta fungerar, låt oss titta på ett sista exempel. Vi förstärker komplexiteten här så att du kan börja förstå hur denna kunskap kan tillämpas i en verklig världssituation.
Åh snäpp! Jag slår vad om att den här ens tillbringar några av de erfarna läsarna. Många av oss känner inte ens skillnaden mellan de två, mycket mindre vilken man vinner en specificitetsdöd match. Låt oss få igång den här festen.
Vad kommer det att bli? Kommer h2 att vara röd eller blå? Låt oss ta reda på:
Pseudoelementet tar det! Pseudoklassen stod inte en chans. Men varför? Vad bakom kulisserna sker voodoo här? Hur kan vi vara säkra på resultatet innan vi ens försöker det?
Specifikitetsregler
Försök och fel är ett bra sätt att lära sig, men i slutändan finns det bara för många olika möjliga scenarier att springa igenom för att samla in all information som vi borde veta. Vad vi behöver är ett svårt och snabbt sätt att bestämma vilka väljare som webbläsaren lägger större vikt vid och varför.
Det visar sig att det finns faktiska enkla regler som reglerar specificitet. I själva verket finns det till och med ett praktiskt punktsystem:
En given CSS-väljare kan ha några av delarna av detta pussel. Tricket att bestämma specifika är att lägga till dem. Den med högsta poäng vinner. Det är så enkelt.
Ingen gillar matematik men för att testa specificiteten hos en väljare kan vi använda den fantastiska specificitetsräknaren på Keegan Street.
Med detta fantastiska verktyg kan vi skriva in två väljare och en poäng för varje kommer automatiskt att beräknas. Den första väljaren i exemplet innehåller en klass, en pseudoklass och två element (poäng: 0,0,2,2). Den andra väljaren slår ner handen med ett ID, en klass, en pseudoklass och ett element (poäng: 0,1,2,1).
Regeln här, som du kan se, är att väljaren med högsta grad av specificitet vinner.Med andra ord, mer specifika selektörer trumma mindre specifika selektorer.
Med tanke på vårt tidigare exempel på en klass vs ett ID kan vi se varför idet vinner. Dess specificitet är betydligt högre än klassens klass, så det överträder klassen.
Särskilda regler
Med tanke på specificitetsräknaren kan vi räkna ut de flesta scenarier, men det finns några kurvbollar som vi behöver tänka på.
- Universalväljaren (*) är värt 0
- När två väljare har samma specificitet, vinner den sista
- Elements kan aldrig slå en klassväljare, även om du höger dem på
- ! viktigt är Superman, det kan slå upp nästan vad som helst
Den sista här är den mest intressanta, så låt oss ta en titt på ett exempel. Här är några HTML och CSS att överväga:
Enkelt nog, eller hur? Med hjälp av vårt poängsystem, klassen poängen högre än elementet, så rubriken kommer ut röd. Men vad händer om vi kasta Superman i scenariot?
Nu har vi riggt kampen. I det här fallet kommer rubriken faktiskt ut blå! Den viktiga regeln säger,? Skruva dig specificitet? och gör vad den vill ha.
Mindre är mer
Nu när du förstår specificitet kan du manipulera din CSS för att göra mycket galna saker. Kom bara ihåg att med stor kraft kommer stort ansvar.
I CSS är den allmänna regeln att mindre är mer. Ju kortare dina regler desto bättre. Använd aldrig .list ul> li> a när li a kommer att fungera bra. Kortare väljare är effektivare och lättare att läsa. Ibland måste du få fantasi, men låt det vara undantaget, inte regeln.
Ett pussel att lösa
Vänta en dang sekund. Reglerna skulle förklara de resultat vi fick i våra första tester, eller hur? Så vad sägs om den här?
Såvitt jag förstår reglerna slår en pseudoklass ett pseudoelement, varför vinner pseudoelementet här? Kanske har vi fel om vilket är pseudoelementet, låt oss kolla vårt diagram.
Nej. Vi hade rätt om första barnet som pseudoklassen mot första linjen, pseudoelementet. Kanske beräknar vi det fel? Låt oss kolla kalkylatorn:
När det gäller räknaren ska rubriken vara blå eftersom första barnet slår första raden. Men det är inte hur det fungerar i webbläsaren. Vad ger? Kanske är vår räknare bruten, låt oss försöka en annan.
Beroende på detta bör första barnet ha ett högre specificitetsvärde och borde därför vinna? men det gör det inte. Jag har försökt använda synkroniseringen med enkel kolon, byter ordning ingenting fungerar. Pseudoelementet vinner alltid, oavsett vad jag kastar på den.
Det här är det där det verkligen blir nötter, även om jag kasta i ett inline-stilelement, som borde slå nästan vad som helst, kommer dangsaken fortfarande upp röd!
Konceptuellt är detta nästan meningsfullt. Vår pseudoklass är inriktad på hela h2-elementet medan vårt pseudoelement endast riktar sig till den första raden av det elementet, vilket verkar mer specifikt.
Din förklaring här
För att vara uppriktigt ärlig, är jag lite förvirrad här. För det mesta är specificiteten ganska okomplicerad, men jag kan inte tycka att jag bryter med mig om den här. Min instinkt är att det kanske är en sorts arvsproblem, men jag är inte säker. Det kan också vara något liknande :inte() som har särskild betydelse när det gäller specificitet (endast punkterna i parentesen räknas i sig är det en noll).
Som svar på vårt lilla pussel, här är några användbara svar från läsare!
Tim Pietrusky
? Enligt specifikationen är endast ett annat element som omsluter innehållet i den första raden mer specifikt än det första linjens pseudo-element. - CodePen Demo
Thomas
? Tänk på första raden som ett extra element (som span) inuti rubriken, förstör endast första raden, så målet är ett element inuti h2, som
första raden andra raden
Bakgrundsfärgen på h2 skulle bara användas (arv) om inget värde skulle förklaras för :: första linjen?
Vidare läsning
Det har redan skett många bra artiklar som publicerats på specificitet, här är några:
- CSS Specificitet: Saker du borde veta - Smashing Magazine
- Särskilda uppgifter om CSS-specificitet - CSS-tricks
- CSS-specificitet för pokerspelare - jag är en kamera
- Förstå CSS Specificity - Jonathan Snook
- Kraften i CSS-specificitet - DIY-teman
Slutsats
Som vi just såg är CSS-specificitet super enkel, förutom när det är superkomplicerat? Du kan och borde lära dig grunderna så att du kan undvika några oväntade resultat, men när det kommer till det, kan det hända att det kan vara nödvändigt med en bra gammalmodig test och fel om du stöter på en klibbig situation.
Vad tror du? Förstår du specificitet så mycket som du borde? Kan du förklara det förbryllande scenariot som vi stötte på ovan?