Ci sono state occasioni in cui avrei voluto essere in grado di selezionare un elemento genitore con i CSS, e non sono il solo a riguardo. Tuttavia, non esiste una cosa come a Selettore principale in CSS, quindi semplicemente non è possibile per il momento.
In questo tutorial illustreremo alcuni casi in cui un selettore genitore CSS potrebbe rivelarsi utile, insieme ad alcuni possibili soluzioni alternative. Iniziamo!
I selettori CSS ci consentono di individuare elementi, spostandoci verso il basso e attraverso l'albero DOM, diventando più specifici mentre lo facciamo. Ecco un esempio del tipo di selettore che potresti trovare in Bootstrap: percorre l'albero del DOM dal nav.navbar-scuro
elemento, al ul
, il Li
, poi finalmente il a.nav-link
.
.navbar-dark .navbar-nav .nav-item .nav-link
Un selezionatore di genitori ci permetterebbe di tornare indietro su il DOM, mirato agli elementi genitore di certe cose. Ad esempio, potremmo scegliere come target il genitore di .nav-link
elementi utilizzando:
.nav-link :: parent
Nota: questo esempio è puro pseudo codice, non esiste né suggerisce la migliore sintassi possibile!
Disegnare contenuti legacy, con markup e struttura datati, è una sfida classica quando si riprogetta un sito web. Prima di HTML5, ad esempio, in genere un'immagine può essere stata avvolta con un p
, div
, o qualche volta con a campata
insieme a un nidificato p
utilizzato per avvolgere la didascalia dell'immagine. Non c'era un modo standard per avvolgere un'immagine e una didascalia. Più tardi, abbiamo adottato il figura
e figcaption
elementi, rendendo la struttura dei nostri documenti più semantica.
Vogliamo che le immagini del contenuto precedente appaiano come sopra. Ma poiché potrebbero essercene di più div
i tag nel nostro documento, quelli che non contengono affatto le immagini, le seguenti dichiarazioni di stile sarebbero completamente impraticabili.
.div del contenuto della pagina padding: 15px; background-color: # f3f3f3; margine: 10px 0 20px; .page-content div img marging: 0 0 10px; .page-content div .img-caption color: # 999; font-size: 12px; allineamento del testo: centro; Wisplay: blocco;
Applicherebbe il colore di sfondo, il riempimento e i margini a tutti gli elementi div nel contenuto. In realtà vogliamo applicare questi stili esclusivamente a div
elementi che racchiudono un'immagine e una didascalia dell'immagine.
Un altro esempio riguarda il mantenimento del rapporto video incorporato (come da Youtube o Vimeo), oltre a rendere fluido il video. In questi giorni, in gran parte grazie al lavoro investigativo di Dave Rupert e amici, è ampiamente riconosciuto che l'approccio migliore è quello di applicare padding-top
o padding-bottom
all'elemento genitore.
In un mondo reale, tuttavia, potremmo non sapere quale elemento contiene il video. Potremmo trovare alcuni video incorporati racchiusi in un file div
o a p
senza un nome di classe identificabile, rendendo complicato selezionare l'elemento corretto su cui applicare gli stili.
Pertanto, dichiarare gli stili come segue è di nuovo impraticabile in quanto inciderà su tutti i div all'interno del .page-content
compresi quelli che non contengono un video incorporato.
.contenuto della pagina larghezza: 560 px; margin-right: auto; margin-left: auto; margin-top: 30px; .page-content div position: relativo; imbottitura-fondo: 56,25%; .page-content div iframe position: absolute; inizio: 0; larghezza: 100%; altezza: 100%;
Che bello sarebbe selezionare direttamente l'elemento genitore del video!
In questo esempio abbiamo una forma con diversi input. Quando ci concentriamo su uno degli input, viene assegnato un colore di bordo più prominente, evidenziando la posizione dell'utente all'interno del modulo.
A volte potresti anche incontrare la situazione in cui non solo il colore del bordo, ma l'elemento che avvolge l'input è evidenziato, rendendo l'input ancora più prominente:
Input focus modulo.L'elemento genitore potrebbe essere a div
o a p
. Quindi, come possiamo selezionare correttamente l'elemento genitore in base a determinati stati dei suoi discendenti?
Come abbiamo visto, non esiste una cosa come a selettore genitore, quindi selezionare un genitore non è possibile. Potremmo essere tentati di eludere il problema, riconsiderando completamente il design in modo da evitare la selezione del genitore. Ma se ciò non è possibile, ecco alcuni potenziali approcci.
: Ha ()
Selettore Il : ha
il selettore è ufficialmente definito pseudo-classe relazionale. Corrisponde agli elementi in base ai loro discendenti, che sono definiti tra parentesi.
Nell'esempio seguente, si applica a colore di sfondo
a nessuno div
contenente una didascalia dell'immagine. Questo apparentemente affronta il caso 1.
.div di contenuto di pagina: has (.img-caption) padding: 15px; background-color: #ccc;
Oppure, se vogliamo essere più specifici, possiamo riscriverlo per abbinarli div
tag con il .img-caption
come il diretto discendente.
.div di contenuto di pagina: has (> .img-caption) padding: 15px; background-color: #ccc;
Questo selettore è disegnato per il CSS Selector Level 4 anche se nessun browser lo implementa ancora. Dovremo aspettare ancora un po 'prima che questo selettore venga alla luce. Fino ad allora, dai un'occhiata al seguente corso video intitolato CSS of the Future per scoprire come funziona il selettore:
Nessuna singola soluzione CSS può risolvere i nostri problemi qui, quindi vediamo cosa può fare JavaScript per noi. In questo esempio useremo jQuery per le sue solide API, convenienza e compatibilità con i browser. Al momento della scrittura, jQuery fornisce tre metodi per selezionare gli elementi principali.
genitore()
; questo metodo seleziona il genitore immediato dell'elemento mirato. Possiamo sfruttare questo metodo per affrontare tutti i casi d'uso menzionati in precedenza nel tutorial.
Ad esempio, possiamo usare genitore()
per aggiungere una classe speciale all'elemento di wrapping delle immagini all'interno del contenuto.
$ (".img-caption") .parent () .addClass ("has-img-caption");
Il codice sopra selezionerà l'elemento immediato che avvolge l'immagine, indipendentemente dal tipo di elemento, aggiungendo il ha-img-caption
classe per darci più controllo sulla selezione e sugli stili degli elementi, come segue.
genitori ()
nota la forma plurale di questo metodo. Questo metodo ci consente di selezionare gli elementi principali dall'immediato, fino alla radice del documento, a meno che a selettore è specificato come argomento.
$ (".img-caption") .parents () .addClass ("has-img-caption");
Dato l'esempio sopra, il genitori ()
il metodo seleziona completamente da div
etichetta che avvolge immediatamente l'immagine, la successiva div
, e infine il html
, aggiungendo il ha-img-caption
classe a tutti gli elementi.
Tale overkill è ridondante. L'unico elemento che probabilmente avrà bisogno di aggiungere la classe, in questo caso, è l'immediato div
elemento. Quindi lo passiamo nell'argomento del metodo.
$ (".img-caption") .parents ("div") .addClass ("has-img-caption");
Qui, il genitori ()
il metodo percorrerà l'albero genealogico dell'immagine, selezionandone uno div
trovato e dandogli il ha-image-caption
classe.
Se ciò è ancora eccessivo, puoi limitare la selezione a un singolo elemento specificando l'indice. Nell'esempio seguente, applichiamo la classe solo alla prima div
.
var $ parents = $ (".caption") .parents ("div"); $ parents [0] .addClass ("has-img-caption"); // seleziona il primo div add aggiungi la classe.
parentsUntil ()
; questo metodo seleziona gli elementi genitore fino a ma non incluso l'elemento specificato tra parentesi.
$ (".caption") .parentsUntil (".page-content") .addClass ("has-img-caption");
Dato il codice sopra, applicherà il ha-img-caption
classe a tutti gli elementi genitore tranne l'elemento con .page-content
.
In alcuni casi, in cui sono presenti elementi nidificati di gazillion, si utilizza il parentsUntil ()
il metodo è preferibile. È comparabilmente più veloce del genitori ()
metodo in quanto evita di utilizzare il motore di selezione jQuery (Sizzle) per spostarsi attraverso l'intero albero DOM fino alla radice del documento.
Probabilmente avremo un selettore genitore CSS in futuro?
Probabilmente no. Il tipo di selettore genitore che abbiamo discusso sopra è stato proposto numerose volte, ma non ha mai superato la fase di stesura del W3C per diversi motivi. Questi motivi si concentrano in gran parte sulle prestazioni del browser, a causa del modo in cui i browser valutano e eseguono il rendering delle pagine. La cosa più vicina che avremo in futuro è il selettore relazionale, : Ha ()
.
Tuttavia, dal momento che il : Ha ()
non è ancora applicabile, JavaScript e jQuery sono attualmente l'approccio più affidabile. Tieni presente che DOM Traversal è un'operazione costosa che potrebbe influire negativamente sulle prestazioni di rendering del tuo sito. Evitare di utilizzare genitori ()
o parentsUntil ()
con altre operazioni pesanti come animare()
, fadeIn ()
o dissolvenza()
.
Meglio ancora, esaminare la struttura HTML ogni volta che è possibile per vedere se la selezione dell'elemento genitore può essere completamente evitata!