Det har varit tillfällen där jag har önskat att jag kunde välja ett föräldraelement med CSS-och jag är inte ensam i den här frågan. Det finns emellertid inte sånt som a Parent Selector i CSS, så det är helt enkelt inte möjligt för tillfället.
I denna handledning kommer vi att gå igenom några fall där det kan vara bra att ha en CSS-förälderväljare tillsammans med några möjliga lösningar. Låt oss börja!
CSS-väljare tillåter oss att rikta in element, flytta ner och över DOM-trädet, bli mer specifika när vi gör det. Här är ett exempel på vilken typ av väljare du kan hitta i Bootstrap-den reser ner DOM-trädet från nav.navbar-mörker
element till ul
, de li
, då äntligen a.nav-länk
.
.navbar-dark. navbar-nav. nav-item. nav-link
En förälderväljare ger oss möjlighet att resa tillbaka upp DOM, riktade mot överordnade element i vissa saker. Vi skulle till exempel kunna rikta in mot föräldern till .nav-länk
element genom att använda:
.nav-länk :: förälder
Notera: detta exempel är ren pseudokod, den existerar inte eller föreslår den bästa möjliga syntaxen!
Styling äldre innehåll, med daterad markup och struktur, är en klassisk utmaning när du redesigner en webbplats. Innan HTML5, till exempel, kan en bild typiskt ha blivit inslaget med en p
, div
, eller ibland med a spänna
tillsammans med en kapslad p
brukade vikla bildtexten. Det fanns inget vanligt sätt att paketera en bild och bildtext. Senare antog vi figur
och figcaption
element, vilket gör vår dokumentstruktur mer semantisk.
Vi vill att bilderna från det äldre innehållet ska visas som ovan. Men eftersom det kan finnas mer div
taggar i vårt dokument, de som inte innehåller bilder alls, skulle följande stildeklarationer vara helt opraktiska.
.sidinnehåll div padding: 15px; bakgrundsfärg: # f3f3f3; marginal: 10px 0 20px; .sida-innehåll div img marging: 0 0 10px; .sida-innehåll div.img-caption color: # 999; fontstorlek: 12px; text-align: center; Wisplay: block;
Det skulle applicera bakgrundsfärgen, vadderingen och marginalerna till alla div-element i innehållet. Vi vill faktiskt tillämpa dessa stilar uteslutande på div
element som wrap en bild och en bildtextion.
Ett annat exempel ser på att upprätthålla inbäddad video (som från Youtube eller Vimeo), såväl som att göra videovätska. Dessa dagar, till stor del tack vare utredningsarbetet av Dave Rupert och pals, är det allmänt accepterat att det bästa sättet är att tillämpa padding-top
eller padding-botten
till moderelementet.
I en verklig värld kan vi dock inte veta vilket element som innehåller videon. Vi kan hitta några inbäddade videor insvept inom en div
eller a p
utan ett identifierbart klassnamn, vilket gör det svårt att välja rätt element för att tillämpa stilar.
Därför är det igen opraktiskt att deklarera stilar enligt följande, eftersom det kommer att påverka alla delarna inom .page-innehåll
inklusive de som inte innehåller en inbäddad video.
.sidinnehåll bredd: 560px; marginal-höger: auto; marginal-vänster: auto; marginal-topp: 30px; .page-content div position: relative; padding-bottom: 56,25%; .page-content div iframe position: absolute; topp: 0; bredd: 100%; höjd: 100%;
Hur underbart det är att direkt välja videoens grundelement!
I det här exemplet har vi en form med flera ingångar. När vi fokuserar på en av ingångarna får den en mer framträdande gränsvärde, som markerar användarens position i formuläret.
Ibland kan du också stöta på situationen där inte bara gränsvärgen, men elementet som inmatar inmatningen är markerat, vilket gör ingången ännu mer framträdande:
Inmatningsform fokus.Moderelementet kan vara a div
eller a p
. Så, hur kan vi väl välja föräldraelementet baserat på vissa stater av sina efterkommande?
Som vi har täckt finns det ingen sådan sak som en förälderväljare, så att välja en förälder är inte möjligt. Vi kanske frestas att undanröja problemet genom att helt ompröva designen så att val av förälder undviks. Men om det inte är möjligt så är det här några potentiella tillvägagångssätt.
: Har ()
Väljare De : har
väljaren kallas officiellt som relationell pseudoklass. Den matchar element baserat på deras efterkommande, vilka definieras mellan parenteserna.
I följande exempel gäller det a bakgrundsfärg
till någon div
innehållande en bildtextning. Detta hänvisar till synes fall 1.
.sidinnehåll div: har (.img-caption) padding: 15px; bakgrundsfärg: #ccc;
Eller om vi vill vara mer specifika kan vi skriva om det för att matcha alla div
tagga med .img-bildtext
som den direkt ättling.
.sidinnehåll div: har (> .img-caption) padding: 15px; bakgrundsfärg: #ccc;
Denna väljare är utarbetad för CSS Selector Level 4, men ingen webbläsare implementerar den än. Vi måste vänta lite längre innan den här väljaren kommer fram. Fram till dess, ta en titt på följande videokurs med titeln CSS of the Future för att få reda på hur väljaren fungerar:
Ingen enda CSS-lösning kan fixa våra problem här, så låt oss se vad JavaScript kan göra för oss istället. I det här exemplet kommer vi att använda jQuery för dess robusta API, bekvämlighet och webbläsarkompatibilitet. Vid skrivningstillfället tillhandahåller jQuery tre metoder för att välja överordnade element.
förälder()
; den här metoden väljer den omedelbara föräldern för det inriktade elementet. Vi kan utnyttja denna metod för att ta itu med alla våra användningsfall som nämnts tidigare i handledningen.
Till exempel kan vi använda förälder()
att lägga till en specialklass till omslaget av bilderna i innehållet.
$ (".img-caption") .parent () .addClass ("har-img-caption");
Ovanstående kod kommer att välja det omedelbara elementet som omsluter bilden, oavsett elementtyp, lägger till har-img-bildtext
klass för att ge oss mer kontroll över elementvalet och stilerna, enligt följande.
föräldrar()
notera pluralformen av denna metod. Med den här metoden kan vi välja överordnade element från omedelbar, upp till roten i dokumentet, såvida inte a väljare anges som argumentet.
$ (".img-caption") .parents () .addClass ("har-img-caption");
Med tanke på ovanstående exempel, föräldrar()
Metoden väljer hela vägen från div
tagg som omedelbart sveper bilden, nästa div
, och slutligen html
, lägger till har-img-bildtext
klass till alla delar.
Sådan överkill är överflödig. Det enda elementet som sannolikt kommer att behöva få klassen tillagt, är i detta fall den omedelbara div
element. Därför överför vi det i metodargumentet.
$ (".img-caption") .parents ("div") .addClass ("har-img-caption");
Här, den föräldrar()
Metoden kommer att resa genom förfader träd av bilden, välja någon div
hittade och ge den har-image-caption
klass.
Om det fortfarande är överdrivet kan du begränsa valet till ett enda element genom att ange indexet. I följande exempel tillämpar vi endast klassen på den första div
.
var $ föräldrar = $ (".caption") .parents ("div"); $ föräldrar [0] .addClass ("har-img-caption"); // välj den första div add lägg till klassen.
parentsUntil ()
; den här metoden väljer moderelementen upp till men inte inklusive det element som anges i parenteserna.
$ (".caption") .parentsUntil (".page-content") .addClass ("har-img-caption");
Med ovanstående kod kommer det att tillämpas har-img-bildtext
klass till alla moderelementen förutom elementet med .page-innehåll
.
I vissa fall, där du har gazillion-kapslade element, använder du parentsUntil ()
Metoden är att föredra. Det är jämförbart snabbare än föräldrar()
metod eftersom det undviker att använda jQuery-väljarmotorn (Sizzle) för att resa över hela DOM-trädet upp till dokumentrotten.
Kommer vi sannolikt att ha en CSS Parent Selector vid någon tidpunkt i framtiden?
Antagligen inte. Den typ av förälderväljare som vi har diskuterat ovan har föreslagits flera gånger, men den har aldrig gått igenom W3C-utkastet av flera anledningar. Dessa anledningar fokuserar i stor utsträckning på webbläsarens prestanda på grund av hur webbläsare utvärderar och gör sidor. Det närmaste som vi kommer att ha i framtiden är relationsväljaren, : Har ()
.
Men sedan : Har ()
är ännu inte tillämpligt, JavaScript och jQuery är för närvarande det mest pålitliga tillvägagångssättet. Tänk på att DOM Traversal är en kostsam operation som kan påverka din webbplatss prestationsförmåga väldigt. Undvik att använda föräldrar()
eller parentsUntil ()
med andra tunga operationer som animera()
, FadeIn ()
eller tona ut()
.
Bättre än, undersök HTML-strukturen när det är möjligt för att se om valet av moderelementet kan undvikas helt!