Il CSS può rilevare il numero di figli di un elemento?

Probabilmente sto rispondendo alla mia stessa domanda, ma sono estremamente curioso.

So che i CSS possono selezionare i singoli figli di un genitore, ma c’è un supporto per lo stile dei figli di un contenitore, se il genitore ha una certa quantità di figli.

per esempio

container:children(8) .child { //style the children this way if there are 8 children } 

So che sembra strano, ma il mio manager mi ha chiesto di verificarlo, non ho trovato nulla da solo, quindi ho deciso di passare a SO prima di terminare la ricerca.

Una precisazione:

A causa di un fraseggio precedente nella domanda originale, pochi cittadini SO hanno sollevato dubbi sul fatto che questa risposta potrebbe essere fuorviante. Nota che, nei CSS3, gli stili non possono essere applicati a un nodo genitore in base al numero di figli che ha. Tuttavia, gli stili possono essere applicati ai nodes figli in base al numero di fratelli che hanno.


Risposta originale:

Incredibilmente, questo è ora ansible esclusivamente nei CSS3.

 /* one item */ li:first-child:nth-last-child(1) { /* -or- li:only-child { */ width: 100%; } /* two items */ li:first-child:nth-last-child(2), li:first-child:nth-last-child(2) ~ li { width: 50%; } /* three items */ li:first-child:nth-last-child(3), li:first-child:nth-last-child(3) ~ li { width: 33.3333%; } /* four items */ li:first-child:nth-last-child(4), li:first-child:nth-last-child(4) ~ li { width: 25%; } 

Il trucco è selezionare il primo figlio quando è anche l’ultimo bambino. Questo seleziona in modo efficace in base al numero di fratelli.

Il merito di questa tecnica va ad André Luís (scoperto) e Lea Verou (raffinato).

Non ti piace semplicemente i CSS3? 😄

Esempio CodePen:

fonti:

No. Beh, non proprio. Ci sono un paio di selettori che ti possono avvicinare un po ‘, ma probabilmente non funzioneranno nel tuo esempio e non hanno la migliore compatibilità con il browser.

:only-child

Il :only-child è uno dei pochi veri selettori di conteggio nel senso che viene applicato solo quando c’è un figlio del genitore dell’elemento. Usando il tuo esempio idealizzato, si comporta come i children(1) probabilmente lo farebbero.

:nth-child

Il selettore :nth-child potrebbe effettivamente portarti dove vuoi andare, a seconda di cosa stai davvero cercando di fare. Se vuoi modellare tutti gli elementi se ci sono 8 bambini, sei sfortunato. Se, tuttavia, vuoi applicare gli stili all’ottavo e agli elementi successivi, prova questo:

 p:nth-child( n + 8 ){ /* add styles to make it pretty */ } 

Sfortunatamente, queste probabilmente non sono le soluzioni che stai cercando. Alla fine, probabilmente dovrai usare un po ‘di magia di Javascript per applicare gli stili in base al conteggio – anche se dovessi usare uno di questi, dovresti dare un’occhiata alla compatibilità del browser prima di andare con un puro Soluzione CSS

W3 Spec. CSS3 su pseudo-classi

EDIT Ho letto la tua domanda in modo un po ‘diverso – ci sono un paio di altri modi per lo stile del genitore , non dei bambini. Permettetemi di lanciare alcuni altri selettori a modo vostro:

:empty e :not

Questo stili elementi che non hanno figli. Non è utile di per sé, ma se abbinato a :not selector, puoi definire solo gli elementi che hanno figli:

 div:not(:empty) { /* We know it has stuff in it! */ } 

Non puoi contare quanti bambini sono disponibili con CSS puro qui, ma è un altro interessante selettore che ti permette di fare cose interessanti.

NOTA: questa soluzione restituirà i figli di serie di determinate lunghezze, non l’elemento padre come richiesto. Spero che sia ancora utile.

Andre Luis ha proposto un metodo: http://lea.verou.me/2011/01/styling-children-based-on-their-number-with-css3/ Sfortunatamente, funziona solo in IE9 e versioni successive.

In sostanza, si combina: nth-child () con altre pseudo classi che si occupano della posizione di un elemento. Questo approccio consente di specificare elementi da insiemi di elementi con lunghezze specifiche .

Ad esempio :nth-child(1):nth-last-child(3) corrisponde al primo elemento di un set mentre è anche il terzo elemento dalla fine del set. Questo fa due cose: garantisce che il set abbia solo tre elementi e che noi abbiamo il primo dei tre. Per specificare il secondo elemento del set di tre elementi, useremmo :nth-child(2):nth-last-child(2) .

Esempio 1: seleziona tutti gli elementi dell’elenco se il set ha tre elementi:

 li:nth-child(1):nth-last-child(3), li:nth-child(2):nth-last-child(2), li:nth-child(3):nth-last-child(1) { width: 33.3333%; } 

Esempio 1 alternativa da Lea Verou:

 li:first-child:nth-last-child(3), li:first-child:nth-last-child(3) ~ li { width: 33.3333%; } 

Esempio 2: target dell’ultimo elemento del set con tre elementi dell’elenco:

 li:nth-child(3):last-child { /* I'm the last of three */ } 

Esempio 2 alternativa:

 li:nth-child(3):nth-last-child(1) { /* I'm the last of three */ } 

Esempio 3: objective secondo elemento dell’insieme con quattro elementi dell’elenco:

 li:nth-child(2):nth-last-child(3) { /* I'm the second of four */ } 

Lavorando sulla soluzione di Matt, ho usato la seguente implementazione Compass / SCSS.

 @for $i from 1 through 20 { li:first-child:nth-last-child( #{$i} ), li:first-child:nth-last-child( #{$i} ) ~ li { width: calc(100% / #{$i} - 10px); } } 

Questo ti consente di espandere rapidamente il numero di elementi.

sì, possiamo farlo usando l’ennesimo bambino in questo modo

 div:nth-child(n + 8) { background: red; } 

Questo farà diventare rosso l’ottavo figlio div in poi. Spero che questo ti aiuti…

Inoltre, se qualcuno dice mai “hey, non possono essere fatti con stile usando i CSS, usa JS !!!” dubitali immediatamente. I CSS sono estremamente flessibili al giorno d’oggi

Esempio: http://jsfiddle.net/uWrLE/1/

Nell’esempio i primi 7 bambini sono blu, poi 8 in poi sono rossi …

Se hai intenzione di farlo in puro CSS (usando scss) ma hai diversi elementi / classi all’interno della stessa class genitore puoi usare questa versione !!

  &:first-of-type:nth-last-of-type(1) { max-width: 100%; } @for $i from 2 through 10 { &:first-of-type:nth-last-of-type(#{$i}), &:first-of-type:nth-last-of-type(#{$i}) ~ & { max-width: (100% / #{$i}); } } 

No, non c’è nulla di simile in CSS. È tuttavia ansible utilizzare JavaScript per calcolare il numero di bambini e applicare gli stili.