Lascia che sia il CSS a decidere il layout: gallerie che si adattano al numero di elementi
Con :has(), :nth-child() e una custom property puoi ottenere griglie “intelligenti” senza classi modificatrici, props o condizioni in JavaScript. Quando progetti un componente “gallery”, la tentazione è sempre la stessa: aggiungere una prop, una classe modificatrice o una condizione lato JS per dire

quante colonne usare. Il problema è che così il layout smette di essere un comportamento emergente del contenuto e diventa una configurazione manuale. E ogni volta che il numero di elementi cambia (filtri, paginazione, A/B test, contenuti dinamici) ti ritrovi a inseguire edge case. Con un po’ di CSS moderno, invece, puoi far sì che sia il componente a adattarsi automaticamente in base a quanti elementi contiene.
Immagina una regola semplice e pragmatica, ad esempio: 2 o 4 item → 2 colonne (più armonioso) 6 item → 3 colonne (spesso perfetto) 7+ item → 4 colonne (riempi meglio lo spazio) Niente classi tipo .gallery--two-cols, niente JS che conta i figli. Solo CSS. Partiamo con una grid normale, ma invece di fissare direttamente il numero di colonne, lo facciamo passare da una custom property. .gallery { --gallery-columns: 3; /* default / fallback */ display: grid; grid-template-columns: repeat(var(--gallery-columns), 1fr); gap: 1rem; } Questo dettaglio è fondamentale: il layout diventa “parametrico”.
Noi, poi, cambiamo --gallery-columns solo quando serve. Il selettore :has() permette di selezionare un elemento in base a ciò che contiene. È esattamente quello che ci serve. Per esempio: “questa gallery ha 6 o più elementi”.
.gallery:has(> :nth-child(6)) { /* qui dentro sei sicuro che esistono almeno 6 children */ } Questa forma è utilissima per soglie: 6+, 7+, 10+… Se vuoi essere più preciso, puoi verificare che l’nth-child(N) sia anche :last-child. .gallery:has(> :nth-child(5):last-child) { /* esattamente 5 elementi */ } È potente, ma può diventare verboso se inizi a gestire molti numeri. Per layout responsive rispetto al contenuto, spesso ti basta distinguere pari/dispari. Esempio concettuale: “se il numero di item è pari, fai X”.
In CSS lo puoi esprimere cercando un figlio che sia contemporaneamente even e last-child. .gallery:has(> :nth-child(even):last-child) { /* numero di figli pari */ } .gallery:has(> :nth-child(odd):last-child) { /* numero di figli dispari */ } È un pattern sorprendentemente utile per gallerie e card grid. Torniamo alla regola obiettivo: default 3 colonne 2 o 4 item → 2 colonne 6 item → rimane 3 (quindi non tocchiamo) 7+ item → 4 colonne Già fatto: .gallery { --gallery-columns: 3; display: grid; grid-template-columns: repeat(var(--gallery-columns), 1fr); gap: 1rem; } Qui vogliamo intercettare i casi “belli” (2 e 4), evitando di degradare i 6 a 2 colonne. .gallery:has(> :nth-child(even):last-child):not(:has(> :nth-child(6))) { --gallery-columns: 2; } Cosa sta succedendo: :has(> :nth-child(even):last-child) → il totale è pari :not(:has(> :nth-child(6))) → esclude 6 o più elementi Risultato pratico: colpisce 2 e 4, non colpisce 6, 8, 10… .gallery:has(> :nth-child(7)) { --gallery-columns: 4; } Nota importante: l’ordine delle regole conta.
Se definisci il caso “7+” dopo, sovrascrive eventuali impostazioni precedenti. Niente API extra del componente: il markup resta pulito. Meno stati da gestire: il componente reagisce al contenuto, non a un flag. Meno bug ai bordi: filtri, sorting e contenuti dinamici non rompono il layout.
Separazione dei ruoli: il layout è responsabilità del CSS, non del rendering. Non significa “mai JS”: significa usare JS solo quando serve davvero, e non per compensare una cosa che il CSS può già esprimere. :has() è una feature moderna: in molti progetti ormai è utilizzabile serenamente, ma va comunque verificata la compatibilità con i browser target. Se devi supportare browser più vecchi, puoi mantenere --gallery-columns: 3 come fallback e accettare un comportamento meno sofisticato.
Mantieni le regole poche e leggibili: la potenza dei selettori non deve trasformarsi in un puzzle. Una gallery “intelligente” non richiede per forza classi modificatrici o logiche condizionali nel codice applicativo. Con una grid parametrica via custom property e qualche selettore mirato (:has() + :nth-child()), puoi far sì che il layout segua automaticamente il contenuto. Il risultato è un CSS più robusto: meno configurazione manuale, meno ramificazioni, più coerenza visiva.
In altre parole: lascia che sia il CSS a fare il lavoro sporco del layout. Articolo originale: https://frontendfacile.it/blog/lascia-che-sia-il-css-a-decidere-il-layout-gallerie-che-si-adattano-al-numero-di
Key Takeaways
- •Il problema è che così il layout smette di essere un comportamento emergente del contenuto e diventa una configurazione manuale.
- •This story was reported by Dev.to, covering developments in the dev space.
- •AI advancements continue to reshape industries — read the full article on Dev.to for complete coverage.
📖 Continue reading the full article:
Read Full Article on Dev.to →

