Velge foreldreelementer med CSS og jQuery

Det har vært tilfeller der jeg har ønsket at jeg kunne velge et foreldreelement med CSS, og jeg er ikke alene i denne saken. Det er imidlertid ikke slikt som a Foreldrevelger i CSS, så det er rett og slett ikke mulig for tiden.

I denne opplæringen vil vi gå gjennom noen få tilfeller der det å ha en CSS foreldrevelger kan komme til nytte, sammen med noen mulige løsninger. La oss komme i gang!

Vent, hva er en foreldrevelger?

CSS-seleksjonene tillater oss å målrette elementer, flytte ned og over DOM-treet, bli mer spesifikke som vi gjør det. Her er et eksempel på hva slags selector du kan finne i Bootstrap-den beveger seg ned fra DOM-treet fra nav.navbar-dark element, til ul, de li, så endelig a.nav-link.

.navbar-dark. navbar-nav. nav-item. nav-link 

 En foreldrevelger vil tillate oss å reise tilbake opp DOM, rettet mot foreldreelementene i visse ting. For eksempel vil vi kunne målrette mot forelderen til .nav-link elementer ved å bruke:

.nav-link :: foreldre 

Merk: dette eksemplet er ren pseudokode, den eksisterer ikke eller foreslår best mulig syntaks!

Sak 1: Styling Legacy Content

Styling eldre innhold, med datert oppslag og struktur, er en klassisk utfordring når du redesignerer et nettsted. Før HTML5, for eksempel, kan et bilde typisk være pakket inn med en p, div, eller noen ganger med en span sammen med en nestet p brukes til å vikle bildeteksten. Det var ingen vanlig måte å pakke inn et bilde og bildetekst på. Senere vedtok vi figur og figcaption elementer, noe som gjør vår dokumentstruktur mer semantisk.

Vi vil at bildene fra arvinnholdet skal vises som ovenfor. Men siden det kan være mer div merker i dokumentet vårt, de som ikke inneholder bilder i det hele tatt, ville følgende stildeklarasjoner være helt upraktiske.

.side-innhold div polstring: 15px; bakgrunnsfarge: # f3f3f3; margin: 10px 0 20px;  .side-innhold div img marging: 0 0 10px;  .side-innhold div .img-caption color: # 999; skriftstørrelse: 12px; tekst-align: center; Wisplay: blokk; 

Det ville bruke bakgrunnsfargen, polstring og marginer til alle div-elementene i innholdet. Vi ønsker faktisk å bruke disse stilene utelukkende til div elementer som pakker inn et bilde og en bildetekst.

Tilfelle 2: Vedlikeholde videoforhold

Et annet eksempel ser på å opprettholde innebygd video (som fra Youtube eller Vimeo), i tillegg til å lage video-væsken. I disse dager, i stor grad takket være undersøkelsesarbeidet av Dave Rupert og vennene, er det allment akseptert at den beste tilnærmingen er å søke padding-top eller padding-bottom til foreldreelementet.

Kodestykke fra CSS-triks: Væskebreddsvideo

I en ekte verden kan vi kanskje ikke vite hvilket element som inneholder videoen. Vi kan finne noen innebygd video innpakket i en div eller a p uten et identifiserbart klassenavn, gjør det vanskelig å velge riktig element som skal brukes på stilene. 

Derfor erklærer stilene som følger det igjen upraktisk siden det vil påvirke alle divene innenfor .side-innhold inkludert de som ikke inneholder en innebygd video.

.sideinnhold bredde: 560px; margin-høyre: auto; margin-left: auto; margin-topp: 30px;  .page-content div posisjon: relative; polstring bunn: 56,25%;  .side-innhold div iframe posisjon: absolutt; topp: 0; bredde: 100%; høyde: 100%; 

Hvor fantastisk det ville være å direkte velge videoens foreldreelement!

Sak 3: Svar på skjemainngang

I dette eksemplet har vi et skjema med flere innganger. Når vi fokuserer på en av inngangene, blir den gitt en mer fremtredende grensefarge, som fremhever brukerens posisjon i skjemaet.

Noen ganger kan du også komme over situasjonen der ikke bare grensefargen, men elementet som pakker innspillet er uthevet, noe som gjør innspillet enda mer fremtredende:

Input form fokus.

Foreldreelementet kan være a div eller a p. Så, hvordan kan vi riktig velge foreldreelementet basert på bestemte stater av sine etterkommere?

Mulige løsninger

Som vi har dekket, er det ikke noe som a foreldrevelger, så det er ikke mulig å velge en forelder. Vi kan bli fristet til å oppsøke problemet, ved å helt gjennomgå designen slik at valg av foreldre unngås. Men hvis det ikke er mulig så er det noen potensielle tilnærminger.

Bruke CSS : Er () Selector 

De : har Selector er offisielt referert til som relasjonell pseudoklasse. Den samsvarer med elementer basert på deres etterkommere, som er definert mellom parentesene. 

I følgende eksempel gjelder det a bakgrunnsfarge til hva som helst div inneholder et bilde bildetekst. Dette tilsier tilsynelatende tilfelle 1.

.side-innhold div: har (.img-caption) polstring: 15px; bakgrunnsfarge: #ccc; 

Eller, hvis vi vil være mer spesifikke, kan vi skrive om det for å matche alle div tag med .img-bildetekst som direkte kommer.

.side-innhold div: har (> .img-bildetekst) polstring: 15px; bakgrunnsfarge: #ccc; 

Denne velgeren er utarbeidet for CSS Selector Level 4, selv om ingen nettlesere implementerer den enda. Vi må vente litt lenger før denne velgeren kommer til syne. Inntil da, ta en titt på følgende videokurs med tittelen CSS of the Future for å finne ut hvordan velgeren fungerer:

  • Den: har pseudoklasse
  • Kombinerer: har og: ikke

Bruke jQuery Parent Selector

Ingen enkelt CSS-løsning kan løse våre problemer her, så la oss se hva JavaScript kan gjøre for oss i stedet. I dette eksemplet skal vi bruke jQuery for sin robuste API, bekvemmelighet og nettleserkompatibilitet. Når du skriver, gir jQuery tre metoder for å velge foreldreelementer.

ordnede (); Denne metoden velger den nærmeste overordnet av det målrettede elementet. Vi kan utnytte denne metoden for å løse alle våre brukssaker som er nevnt tidligere i opplæringen.

Bildestruktur i eldre innhold.

For eksempel kan vi bruke ordnede () å legge til en spesiell klasse for innpakningselementet av bildene i innholdet.

$ (".img-caption") .parent () .addClass ("har-img-caption"); 

Ovennevnte kode vil velge det umiddelbare elementet som pakker inn bildet, uansett elementstype, og legger til har-img-bildetekst klasse for å gi oss mer kontroll over elementvalg og stiler, som følger.

Bildestruktur i eldre innhold med en ekstra klasse.

foreldre() Legg merke til flertallsformen av denne metoden. Denne metoden lar oss velge foreldreelementene fra den umiddelbare, opp til roten av dokumentet, med mindre a velger er angitt som argumentet.

$ (".img-caption") .parents () .addClass ("har-img-caption"); 

Gitt det ovennevnte eksempelet, foreldre() Metoden velger hele veien fra div tag som umiddelbart bryter bildet, det neste div, og til slutt den html, legger til har-img-bildetekst klasse til alle elementer.

Klassen has-img-caption brukes med foreldrene () -metoden.

Slik overkilling er overflødig. Det eneste elementet som sannsynligvis vil ha klassen lagt til, i dette tilfellet, er den umiddelbare div element. Derfor passerer vi det i metode argumentet.

$ (".img-caption") .parents ("div") .addClass ("har-img-caption"); 

Her, den foreldre() Metoden vil reise gjennom forfedret av bildet, velge noen div funnet og gir det har-image-caption klasse.

Hvis det fortsatt er overbærende, kan du begrense valget til et enkelt element ved å spesifisere indeksen. I følgende eksempel bruker vi kun klassen til den første div.

var $ foreldre = $ (".caption") .parents ("div"); $ foreldre [0] .addClass ("har-img-caption"); // velg den første div add legg til klassen. 

parentsUntil (); denne metoden velger foreldreelementene opp til men ikke inkludert elementet angitt i parentesene.

$ (".caption") .parentsUntil (".page-content") .addClass ("har-img-caption"); 

Gitt ovenstående kode, vil den gjelde har-img-bildetekst klasse til alle foreldreelementene unntatt elementet med .side-innhold.

I noen tilfeller, hvor du har gazillion nestede elementer, bruker du parentsUntil () metoden er å foretrekke. Det er sammenlignbart raskere enn foreldre() metode som det unngår å bruke jQuery-selektormotoren (Sizzle) for å reise over hele DOM-treet opp til dokumentroten.

Wrapping Up

Er det sannsynlig at vi har en CSS Parent Selector på et tidspunkt i fremtiden?

Sannsynligvis ikke. Den slags foreldrevelger som vi har diskutert ovenfor, har blitt foreslått mange ganger, men den har aldri bestått W3C-utkastet av flere grunner. Disse grunnene fokuserer i stor grad på nettleserens ytelse, på grunn av måten nettlesere evaluerer og gjengir sider. Det nærmeste vi har i fremtiden er relasjonsvelgeren, : Er ().

Men siden : Er () er ikke aktuelt, JavaScript og jQuery er for øyeblikket den mest pålitelige tilnærmingen. Husk at DOM Traversal er en kostbar operasjon som kan påvirke nettstedets ytelsesytelse. Unngå å bruke foreldre() eller parentsUntil () med andre tunge operasjoner som animere (), fadeIn () eller fadeout ()

Enda bedre, undersøk HTML-strukturen når det er mulig for å se om valg av overordnet element kan unngås fullstendig!

Ytterligere ressurser

  • CSS Nivå 4 Selektorer for å se etter
  • CSS velger for: foreldre målretting (takk)
  • Hvorfor vi ikke har foreldrevelger