Selectarea elementelor părinte cu CSS și jQuery

Au fost ocazii în care mi-am dorit să pot selecta un element părinte cu CSS - și nu sunt singur în această chestiune. Cu toate acestea, nu există un astfel de lucru ca a Selectorul părintelui în CSS, deci pur și simplu nu este posibil pentru moment.

În acest tutorial vom trece prin câteva cazuri în care un selector de părinte CSS ar putea fi util, împreună cu unele posibile soluții. Să începem!

Așteaptă, ce este selectorul părinte??

Selectorii CSS ne permit să direcționăm elementele, deplasându-ne în jos și prin arborele DOM, devenind tot mai specific, pe măsură ce facem acest lucru. Iată un exemplu de fel de selector pe care îl puteți găsi în Bootstrap - călătorește în jos de pe arborele DOM din nav.navbar-întuneric element, la ul, Li, apoi în cele din urmă a.nav-link.

.navbar-întuneric .navbar-nav .nav-element .nav-link 

 Un selector părinte ne-ar permite să călătorim înapoi sus DOM, care vizează elementele părinte ale anumitor lucruri. De exemplu, am putea să vizăm parintele din .nav-link elemente prin utilizarea:

.nav-link :: părinte 

Notă: acest exemplu este cod pseudo pur, nu există și nu sugerează cea mai bună sintaxă posibilă!

Cazul 1: Conținutul vechi al stilului

Conținutul vechi de stil, cu marcarea și structura dată, este o provocare clasică atunci când reproiectați un site Web. Înainte de HTML5, de exemplu, o imagine ar putea fi, de obicei, înfășurată cu a p, div, sau uneori cu deschidere împreună cu un imbricat p folosit pentru a împacheta legenda imaginii. Nu a existat un mod standard de a împacheta o imagine și o legendă. Mai târziu, am adoptat figura și figcaption elemente, făcând structura noastră de document mai semantică.

Vrem ca imaginile din conținutul vechi să apară ca mai sus. Dar, deoarece pot exista mai multe div etichetele din documentul nostru, care nu conțin imagini deloc, următoarele declarații de stil ar fi complet nepractice.

.conținutul paginii div padding: 15px; fundal-culoare: # f3f3f3; margine: 10px 0 20px;  .page-content div img marginare: 0 0 10px;  .page-content div .img-caption culoare: # 999; font-size: 12px; text-align: centru; Wisplay: bloc; 

Aceasta ar aplica culoarea de fundal, umplutura și marginile tuturor elementelor div din conținut. De fapt, dorim să aplicăm exclusiv aceste stiluri div elemente care înfășoară o imagine și o subtitrare a imaginii.

Cazul 2: Menținerea raportului video

Un alt exemplu se referă la menținerea raportului încorporat (cum ar fi de la Youtube sau Vimeo), precum și la realizarea fluidului video. Aceste zile, în mare parte datorită activității de investigare a lui Dave Rupert și a prietenilor, se acceptă pe scară largă că se aplică cea mai bună abordare padding-top sau umplutură de fund la elementul părinte.

Fragment de cod din CSS-trucuri: videoclip cu lățime fluidă

Într-o lume reală, cu toate acestea, s-ar putea să nu știm ce element conține videoclipul. S-ar putea să găsim unele videoclipuri încorporate înfășurate într-un div sau a p fără un nume de clasă identificabil, ceea ce face dificilă selectarea elementului potrivit pe care să se aplice stilurile. 

Prin urmare, declararea stilurilor după cum urmează este din nou nepractică, deoarece va avea impact asupra tuturor divs în cadrul .pagină de conținut inclusiv cele care nu conțin un videoclip încorporat.

.conținutul paginii width: 560px; margin-dreapta: auto; margin-stânga: auto; margin-top: 30px;  .page-content div poziție: relativă; pad-bottom: 56,25%;  .page-content div iframe poziție: absolut; top: 0; lățime: 100%; înălțime: 100%; 

Cât de minunat ar fi să selectați direct elementul părinte al videoclipului!

Cazul 3: Răspunsul la formularul de intrare

În acest exemplu, avem un formular cu mai multe intrări. Atunci când ne concentrăm asupra uneia dintre intrări, se dă o culoare de graniță mai proeminentă, evidențiind poziția utilizatorului în formular.

Uneori, de asemenea, puteți întâlni situația în care nu numai culoarea frontală, ci elementul care împachetează intrarea este evidențiat, ceea ce face ca intrarea să fie și mai proeminentă:

Introduceți formularul de focalizare.

Elementul părinte ar putea fi a div sau a p. Deci, cum putem selecta corect elementul părinte bazat pe anumite stări ale descendenților săi?

Posibile soluții

Așa cum am acoperit, nu există nici un lucru ca a părinte selector, astfel încât selectarea unui părinte nu este posibilă. S-ar putea să fim tentați să evităm problema, reconsiderând complet designul, astfel încât să se evite selectarea părintelui. Dar dacă acest lucru nu este posibil, atunci sunt câteva abordări potențiale.

Utilizarea CSS : Are () Selector 

 : are selectorul este denumit oficial pseudo-clasa relațională. Se potrivește elementelor bazate pe descendenții lor, care sunt definite între paranteze. 

În exemplul următor, se aplică a culoare de fundal la oricine div care conține o imagine de captare. Acest lucru se referă aparent la cazul 1.

.conținutul paginii div: are (.img-caption) padding: 15px; fundal-culoare: #ccc; 

Sau, dacă vrem să fim mai specifici, o putem rescrie pentru a se potrivi cu orice div eticheta cu .img-legendă dupa cum direct descendent.

.pagina de conținut div: are (> .img-caption) padding: 15px; fundal-culoare: #ccc; 

Acest selector este proiectat pentru CSS Selector Level 4, deși niciun browser nu îl implementează încă. Va trebui să așteptăm un pic mai mult înainte ca acest selector să iasă la lumină. Până atunci, aruncăm o privire la următorul curs video intitulat CSS of the Future pentru a afla cum funcționează selectorul:

  • Pseudo-Class
  • Combinarea: are și nu: nu

Utilizarea selectorului părinte jQuery

Nici o soluție CSS nu poate rezolva problemele noastre aici, așa că să vedem ce poate face JavaScript în locul nostru. În acest exemplu, vom folosi jQuery pentru API-urile sale robuste, comoditate și compatibilitate cu browser-ul. La momentul scrisului, jQuery oferă trei metode pentru selectarea elementelor părinte.

mamă(); această metodă selectează părintele imediat al elementului vizat. Putem folosi această metodă pentru a aborda toate cazurile de utilizare menționate anterior în tutorial.

Structura imaginii în conținutul vechi.

De exemplu, putem folosi mamă() pentru a adăuga o clasă specială elementului de înfășurare a imaginilor din cadrul conținutului.

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

Codul de mai sus va selecta elementul imediat care înfășoară imaginea, indiferent de tipul elementului, adăugând are-img-legendă pentru a ne da mai mult control asupra selecției și stilurilor elementelor, după cum urmează.

Structura imaginii în conținutul vechi cu o clasă suplimentară.

părinţi() observați forma plurală a acestei metode. Această metodă ne permite să selectăm elementele părinte de la elementul imediat, până la rădăcina documentului, cu excepția cazului în care a selector este specificată ca argument.

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

Având în vedere exemplul de mai sus, părinţi() metoda selectează tot drumul de la div eticheta care înfășoară imediat imaginea, următoarea div, și în cele din urmă html, adăugând are-img-legendă clasa tuturor elementelor.

Clasa has-img-caption aplicată cu metoda parent ().

O astfel de depășire este redundantă. Singurul element care va trebui probabil să aibă clasa adăugată, în acest caz, este imediat div element. Prin urmare, îl transmitem în argumentul metodei.

$ (".img-caption"). părinți ("div") .addClass ("has-img-caption"); 

Aici părinţi() metoda va călători prin arborele strămoș al imaginii, selectând orice div găsite și oferindu-le are-imagine-legendă clasă.

Dacă acest lucru este încă amețitor, puteți restrânge selecția la un singur element prin specificarea indexului. În exemplul următor, vom aplica clasa numai la primul div.

var $ părinți = $ (".caption"). părinți ("div"); $ părinți [0] .addClass ("has-img-caption"); // selectați primul div adăugați clasa. 

parentsUntil (); această metodă selectează elementele părinte până la dar fără a include elementul specificat în paranteze.

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

Având în vedere codul de mai sus, acesta va aplica are-img-legendă clasă la toate elementele părinte, cu excepția elementului cu .pagină de conținut.

În unele cazuri, în cazul în care aveți elemente gazillion elemente imbricate, folosind parentsUntil () este preferabilă metoda. Este comparabil mai rapid decât părinţi() deoarece evită folosirea motorului selector jQuery (Sizzle) pentru a călători în întregul copac DOM până la rădăcina documentului.

Înfășurarea în sus

Este probabil să avem un selector de părinți CSS la un moment dat în viitor?

Probabil ca nu. Tipul selectorului părinte pe care l-am discutat mai sus a fost propus de mai multe ori, dar nu a trecut niciodată proiectul de proiect W3C din mai multe motive. Aceste motive se concentrează în mare parte pe performanța browserului, datorită modului în care browserele evaluează și fac pagini. Cel mai apropiat lucru pe care îl vom avea în viitor este selectorul relațional, : Are ().

Cu toate acestea, din moment ce : Are () nu este încă aplicabilă, JavaScript și jQuery sunt în prezent cea mai fiabilă abordare. Rețineți că DOM Traversal este o operațiune costisitoare care poate afecta performanța rendering-ului site-ului dvs.. Evita sa folosesti părinţi() sau parentsUntil () cu alte operații grele cum ar fi anima(), fadeIn () sau fadeOut ()

Mai bine, examinați structura HTML ori de câte ori este posibil pentru a vedea dacă selectarea elementului părinte poate fi evitată complet!

Resurse suplimentare

  • Selectorii CSS de nivel 4 pentru a fi atenți la
  • Selector CSS pentru: direcționarea părinte (vă rugăm)
  • De ce nu avem un selector părinte