Selecteren van bovenliggende elementen met CSS en jQuery

Er zijn gelegenheden geweest waar ik wenste dat ik een ouderelement met CSS kon selecteren - en ik ben niet de enige in deze kwestie. Er is echter niet zoiets als een Ouderkiezer in CSS, dus het is eenvoudigweg voorlopig niet mogelijk.

In deze zelfstudie bespreken we enkele gevallen waarin een CSS-bovenliggende selector van pas kan komen, samen met enkele mogelijke oplossingen. Laten we beginnen!

Wacht, wat is een ouderselectie?

CSS-selectors stellen ons in staat om elementen te targeten, naar beneden te gaan en over de DOM-boom heen te gaan, terwijl we specifieker worden. Hier is een voorbeeld van het soort selector dat je in Bootstrap zou kunnen vinden - het reist door de DOM-tree vanaf de nav.navbar-dark element, naar de ul, de li, dan eindelijk de a.nav-koppeling.

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

 Met een bovenliggende selector zouden we terug kunnen reizen omhoog de DOM, gericht op de ouderelementen van bepaalde dingen. We kunnen bijvoorbeeld de ouder van targeten .nav-koppeling elementen door gebruik te maken van:

.nav-link :: parent 

Notitie: dit voorbeeld is pure pseudo-code, het bestaat niet en suggereert niet de best mogelijke syntaxis!

Case 1: Legacy-inhoud stylen

Het stylen van verouderde content, met gedateerde markup en structuur, is een klassieke uitdaging bij het opnieuw ontwerpen van een website. Vóór HTML5 kan een afbeelding bijvoorbeeld zijn ingepakt met een p, div, of soms met een span samen met een genest p gebruikt om het bijschrift van de afbeelding om te slaan. Er was geen standaardmanier om een ​​afbeelding en bijschrift in te pakken. Later hebben we de figuur en figcaption elementen, waardoor onze documentstructuur semantischer wordt.

We willen dat de afbeeldingen van de oude inhoud worden weergegeven zoals hierboven. Maar aangezien er misschien meer zijn div tags in ons document, degenen die helemaal geen afbeeldingen bevatten, de volgende stijlverklaringen zouden volledig onpraktisch zijn.

.pagina-inhoud div opvulling: 15px; achtergrondkleur: # f3f3f3; marge: 10px 0 20px;  .page-content div img marging: 0 0 10px;  .page-content div .img-caption color: # 999; lettergrootte: 12px; text-align: center; Wisplay: blok; 

Het zou de achtergrondkleur, opvulling en marges toepassen op alle div-elementen in de inhoud. We willen deze stijlen eigenlijk uitsluitend toepassen op div elementen die een afbeelding en een afbeeldingbijschrift omwikkelen.

Geval 2: handhaving van de videoverhouding

Een ander voorbeeld kijkt naar het onderhouden van embedded video (zoals van Youtube of Vimeo) ratio, evenals het maken van video-vloeistof. Deze dagen, grotendeels dankzij het onderzoekswerk van Dave Rupert en vrienden, wordt algemeen aangenomen dat de beste aanpak is om toe te passen padding-top of padding-bottom naar het bovenliggende element.

Codefragment van CSS-Tricks: video met vloeiende breedte

In een echte wereld weten we echter niet welk element de video bevat. Mogelijk vinden we een ingesloten video verpakt in een div of a p zonder een identificeerbare klassenaam, waardoor het lastig is om het juiste element te selecteren waarop de stijlen moeten worden toegepast. 

Daarom is het opnieuw onpraktisch om de stijlen als volgt te declareren, omdat deze van invloed zijn op alle divs binnen de .pagina inhoud inclusief degenen die geen ingesloten video bevatten.

.pagina-inhoud width: 560px; marge-rechts: auto; marge links: auto; margin-top: 30px;  .page-content div position: relative; opvulbodem: 56,25%;  .page-content div iframe position: absolute; boven: 0; breedte: 100%; hoogte: 100%; 

Hoe geweldig zou het zijn om direct het ouderelement van de video te selecteren!

Case 3: Reageren op formulierinvoer

In dit voorbeeld hebben we een formulier met verschillende ingangen. Wanneer we ons concentreren op een van de ingangen, krijgt deze een meer prominente randkleur, waardoor de positie van de gebruiker in het formulier wordt benadrukt.

Soms kom je ook de situatie tegen waar niet alleen de randkleur, maar ook het element dat de invoer omhult, is gemarkeerd, waardoor de invoer nog prominenter wordt:

Formulierfocus invoeren.

Het bovenliggende element kan een zijn div of a p. Dus, hoe kunnen we het ouderelement correct selecteren op basis van bepaalde toestanden van zijn afstammelingen?

Mogelijke oplossingen

Zoals we hebben besproken, bestaat er niet zoiets als een bovenliggende selector, dus het selecteren van een ouder is niet mogelijk. We komen misschien in de verleiding om het probleem te omzeilen, door het ontwerp volledig te heroverwegen, zodat het selecteren van de ouder wordt vermeden. Maar als dat niet mogelijk is, dan zijn hier enkele mogelijke benaderingen.

CSS gebruiken : Heeft () keuzeschakelaar 

De : heeft selector wordt officieel de relationele pseudo-klasse genoemd. Het komt overeen met elementen op basis van hun afstammelingen, die tussen de haakjes zijn gedefinieerd. 

In het volgende voorbeeld is het van toepassing Achtergrond kleur voor wie dan ook div met een afbeelding bijschrift. Dit lijkt case 1 aan te pakken.

.page-content div: heeft (.img-caption) padding: 15px; achtergrondkleur: #ccc; 

Of, als we specifieker willen zijn, kunnen we het herschrijven om het aan te passen div tag met de .img-caption als de direct afstammeling.

.page-content div: heeft (> .img-caption) padding: 15px; achtergrondkleur: #ccc; 

Deze selector is opgesteld voor CSS Selector Level 4, hoewel er nog geen browsers zijn geïmplementeerd. We zullen iets langer moeten wachten voordat deze selector aan het licht komt. Tot die tijd kun je de volgende videocursus met de titel CSS van de Toekomst bekijken om erachter te komen hoe de selector werkt:

  • De: heeft een pseudo-klasse
  • Combineren: heeft en: niet

De jQuery-parentenselectie gebruiken

Geen enkele CSS-oplossing kan onze problemen hier oplossen, dus laten we eens kijken wat JavaScript voor ons kan doen. In dit voorbeeld gaan we jQuery gebruiken vanwege de krachtige API's, het gemak en de browsercompatibiliteit. Op het moment van schrijven biedt jQuery drie methoden voor het selecteren van bovenliggende elementen.

ouder(); deze methode selecteert de directe ouder van het doelelement. We kunnen deze methode gebruiken om al onze use-cases aan te pakken die eerder in de tutorial zijn genoemd.

Beeldstructuur in verouderde inhoud.

We kunnen bijvoorbeeld gebruiken ouder() om een ​​speciale klasse toe te voegen aan het wikkelelement van de afbeeldingen in de inhoud.

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

De bovenstaande code selecteert het onmiddellijke element dat de afbeelding omwikkelt, ongeacht het elementtype, het toevoegen van de heeft-img-caption klasse om ons meer controle te geven over de elementselectie en stijlen, als volgt.

Beeldstructuur in oudere inhoud met een extra klasse.

ouders() let op de meervoudsvorm van deze methode. Met deze methode kunnen we de bovenliggende elementen selecteren van de directe tot de hoofdmap van het document, tenzij a keuzeschakelaar wordt opgegeven als het argument.

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

Gezien het bovenstaande voorbeeld, de ouders() methode selecteert helemaal vanaf de div tag die de afbeelding onmiddellijk omwikkelt, de volgende div, en ten slotte de html, het toevoegen van de heeft-img-caption klasse voor alle elementen.

De klasse has-img-caption toegepast met de methode parents ().

Dergelijke overkill is overbodig. Het enige element dat waarschijnlijk de klasse moet hebben toegevoegd, in dit geval, is het onmiddellijke div element. Daarom geven we het door in het argument van de methode.

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

Hier de ouders() methode zal reizen door de voorouder boom van de afbeelding, het selecteren van een div gevonden en gevend het heeft-image-caption klasse.

Als dat nog steeds aanmatigend is, kunt u de selectie beperken tot een enkel element door de index op te geven. In het volgende voorbeeld passen we de klasse alleen toe op de eerste div.

var $ parents = $ (".caption") .parents ("div"); $ parents [0] .addClass ("has-img-caption"); // selecteer de eerste div add voeg de class toe. 

parentsUntil (); deze methode selecteert de parent-elementen tot maar niet inbegrepen het element dat tussen haakjes staat.

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

Gezien de bovenstaande code, zal het de heeft-img-caption klasse voor alle bovenliggende elementen behalve het element met .pagina inhoud.

In sommige gevallen, waar je gazillion geneste elementen hebt, gebruik je de parentsUntil () methode heeft de voorkeur. Het is vergelijkbaar sneller dan het ouders() methode omdat het vermijdt om de jQuery-selectorengine (Sizzle) te gebruiken om door de volledige DOM-structuur te reizen naar de documentwortel.

Afsluiten

Hebben we op een gegeven moment in de toekomst waarschijnlijk een CSS Parent Selector??

Waarschijnlijk niet. Het type bovenliggende selector dat we hierboven hebben besproken, is vele malen voorgesteld, maar het is om verschillende redenen nooit door de W3C-ontwerpfase gegaan. Deze redenen zijn grotendeels gericht op browserprestaties, vanwege de manier waarop browsers pagina's evalueren en renderen. Het dichtsbijzijnde dat we in de toekomst zullen hebben, is de relationele selector, : Heeft ().

Echter, sinds de : Heeft () is nog niet van toepassing, JavaScript en jQuery zijn op dit moment de meest betrouwbare benadering. Houd er rekening mee dat DOM Traversal een kostbare bewerking is die de weergaveprestaties van uw site mogelijk negatief beïnvloedt. Vermijd te gebruiken ouders() of parentsUntil () met andere zware operaties zoals animeren (), fadeIn () of Fadeout ()

Beter nog, onderzoek de HTML-structuur waar mogelijk om te zien of het selecteren van het bovenliggende element volledig kan worden voorkomen!

Verdere bronnen

  • CSS Level 4-kiezers om op te letten
  • CSS-selector voor: bovenliggende targeting (alstublieft)
  • Waarom hebben we geen bovenliggende selector