Smakämnen :has()
pseudoklass är, helt enkelt, min nya favorit CSS-funktion. Jag vet att det är för många av er också, åtminstone de av er som deltog i State of CSS-undersökningen. Möjligheten att skriva väljare upp och ner ger oss fler superkrafter som jag aldrig trodde var möjligt.
Jag säger "fler superkrafter" eftersom det redan har funnits massor av riktigt fantastiska smarta idéer publicerade av ett gäng supersmarta människor, som:
Den här artikeln är inte en definitiv guide till :has()
. Det är inte heller här för att upprepa det som redan har sagts. Det är bara jag (hej 👋) som hoppar på tåget för ett ögonblick för att dela med mig av några av de sätt jag mest sannolikt kommer att använda :has()
i mitt dagliga arbete... det vill säga när det officiellt stöds av Firefox som är nära förestående.
När det händer kan du slå vad om att jag börjar använda :has()
över hela stället. Här är några verkliga exempel på saker jag har byggt nyligen och tänkte för mig själv, "Jösses, det här kommer att bli så mycket trevligare en gång :has()
har fullt stöd."
Undvik att behöva nå utanför din JavaScript-komponent
Har du någonsin byggt en interaktiv komponent som ibland behöver påverka stilar någon annanstans på sidan? Ta följande exempel, där <nav>
är en mega meny, och öppna den ändrar färgerna på <header>
innehållet ovanför det.
Jag känner att jag måste göra sånt här hela tiden.
Det här specifika exemplet är en React-komponent som jag gjorde för en webbplats. Jag var tvungen att "nå utanför" React-delen av sidan med document.querySelector(...)
och växla en klass på <body>
, <header>
, eller någon annan komponent. Det är inte slutet på världen, men det känns verkligen lite töntigt. Även på en fullständig React-webbplats (säg en Next.js-webbplats) måste jag välja mellan att hantera en menuIsOpen
ange långt högre upp i komponentträdet, eller gör samma DOM-elementval — vilket inte är särskilt React-y.
Med :has()
, problemet försvinner:
header:has(.megamenu--open) { /* style the header differently if it contains an element with the class ".megamenu--open" */
}
Inget mer att pilla med andra delar av DOM i mina JavaScript-komponenter!
Bättre bordsstrimning UX
Att lägga till alternativa rad "ränder" till dina tabeller kan vara en trevlig UX-förbättring. De hjälper dina ögon att hålla reda på vilken rad du befinner dig på när du skannar bordet.
Men enligt min erfarenhet fungerar detta inte bra på tabeller med bara två eller tre rader. Om du till exempel har en tabell med tre rader i <tbody>
och du "stripar" varje "jämn" rad, kan du sluta med bara en rand. Det är inte riktigt värt ett mönster och kan få användare att undra vad som är så speciellt med den markerade raden.
Använder denna teknik där Bramus använder :has()
att tillämpa stilar baserat på antalet barn, vi kan applicera bordsränder när det finns fler än, säg, tre rader:
Vad ska man bli snyggare? Du kan också välja att bara göra detta om tabellen har minst ett visst antal kolumner också:
table:has(:is(td, th):nth-child(3)) { /* only do stuff if there are three or more columns */
}
Ta bort villkorlig klasslogik från mallar
Jag behöver ofta ändra en sidlayout beroende på vad som finns på sidan. Ta följande rutnätslayout, där placeringen av huvudinnehållet ändrar rutnätsområden beroende på om det finns en sidofält.
Det är något som kan bero på om det finns syskonsidor inställda i CMS. Jag skulle normalt göra detta med malllogik för att villkorligt lägga till BEM modifieringsklasser till layoutomslaget för att ta hänsyn till båda layouterna. Den CSS kan se ut ungefär så här (responsiva regler och andra saker utelämnas för korthetens skull):
/* m = main content */
/* s = sidebar */
.standard-page--with-sidebar { grid-template-areas: 's s s m m m m m m m m m';
}
.standard-page--without-sidebar { grid-template-areas: '. m m m m m m m m m . .';
}
CSS-mässigt är detta helt okej, naturligtvis. Men det gör mallkoden lite rörig. Beroende på ditt mallspråk kan det bli ganska fult att villkorligt lägga till ett gäng klasser, speciellt om du måste göra detta med många barnelement också.
Jämför det med en :has()
-baserat tillvägagångssätt:
/* m = main content */
/* s = sidebar */
.standard-page:has(.sidebar) { grid-template-areas: 's s s m m m m m m m m m';
}
.standard-page:not(:has(.sidebar)) { grid-template-areas: '. m m m m m m m m m . .';
}
Ärligt talat, det är inte mycket bättre CSS-mässigt. Men att ta bort de villkorliga modifieringsklasserna från HTML-mallen är en trevlig vinst om du frågar mig.
Det är lätt att tänka på mikrodesignbeslut för :has()
- som ett kort när det har en bild i sig — men jag tror att det kommer att vara väldigt användbart för dessa makrolayoutändringar också.
Bättre specificitetshantering
Om du läser min sista artikel, du vet att jag håller fast vid specificitet. Om du, som jag, inte vill att dina specificitetspoäng blåser ut när du lägger till :has()
och :not()
genom dina stilar, se till att använda :where()
.
Det beror på att specificiteten av :has()
är baserad på det mest specifika elementet i dess argumentlista. Så om du har något som ett ID där, kommer din väljare att bli svår att åsidosätta i kaskaden.
Å andra sidan, specificiteten av :where()
är alltid noll, vilket aldrig ökar specificitetspoängen.
/* specificity score: 0,1,0. Same as a .standard-page--with-sidebar modifier class
*/
.standard-page:where(:has(.sidebar)) { /* etc */
}
Framtiden är ljus
Det här är bara några saker som jag ser fram emot att kunna använda i produktionen. CSS-Tricks Almanac har också ett gäng exempel. Vad ser du fram emot att göra med :has()
? Vilken typ av verkliga exempel har du stött på var :has()
hade varit den perfekta lösningen?
- SEO-drivet innehåll och PR-distribution. Bli förstärkt idag.
- Platoblockchain. Web3 Metaverse Intelligence. Kunskap förstärkt. Tillgång här.
- Källa: https://css-tricks.com/more-real-world-uses-for-has/
- 1
- 11
- 7
- 9
- 98
- a
- förmåga
- Able
- Om Oss
- ovan
- Konto
- påverka
- Alla
- redan
- alltid
- fantastiska
- och
- Annan
- Ansök
- tillvägagångssätt
- områden
- Argumentet
- Artikeln
- baserat
- därför att
- Bet
- Bättre
- mellan
- Bit
- Blåser
- byggt
- Bunch
- Kan få
- kortet
- vattenfall
- vissa
- byta
- Förändringar
- barn
- Välja
- klass
- klasser
- cms
- koda
- Kolonner
- komponent
- innehåller
- innehåll
- kunde
- Kurs
- CSS
- beslut
- slutgiltig
- beroende
- Designa
- inte
- gör
- DOM
- inte
- ner
- element
- speciellt
- etc
- Även
- NÅGONSIN
- Varje
- exempel
- exempel
- erfarenhet
- Ögon
- Favoriten
- Leverans
- få
- änden
- firefox
- efter
- Framåt
- från
- fullständigt
- skaffa sig
- ger
- Går
- kommer
- stor
- Rutnät
- rutnät-mall-områden
- styra
- hända
- har
- hjälpa
- här.
- hi
- högre
- Markerad
- html
- HTTPS
- SJUK
- idéer
- bild
- förbättring
- in
- interaktiva
- IT
- JavaScript
- bara en
- Ha kvar
- Snäll
- Vet
- språk
- Efternamn
- Layout
- sannolikt
- liten
- se
- du letar
- Lot
- Makro
- gjord
- Huvudsida
- göra
- hantera
- många
- kanske
- ögonblick
- mer
- mest
- Mozilla
- Behöver
- behov
- Nya
- Nästa
- Next.js
- normalt
- antal
- Officiellt
- ONE
- öppning
- Övriga
- utanför
- del
- särskilt
- reservdelar till din klassiker
- Mönster
- Personer
- perfekt
- Plats
- plato
- Platon Data Intelligence
- PlatonData
- möjlig
- presentera
- pretty
- Problem
- Produktion
- publicerade
- nå
- Reagera
- Läsa
- verkliga världen
- nyligen
- bort
- mottaglig
- RAD
- regler
- Körning
- Nämnda
- Samma
- scanna
- Val
- in
- Dela
- webbplats
- smarta
- So
- lösning
- några
- något
- någonstans
- speciell
- specifik
- specificitet
- starta
- Ange
- rand
- Stripes
- stil
- super
- Som stöds
- bord
- Ta
- TD
- mall
- Smakämnen
- Staten
- världen
- sak
- saker
- trodde
- tre
- hela
- till
- ton
- alltför
- TOTALT
- spår
- sann
- upside
- us
- användning
- användare
- ux
- vänta
- sätt
- Vad
- om
- som
- VEM
- vinna
- undrar
- Arbete
- världen
- värt
- skulle
- skriva
- Om er
- Din
- zephyrnet