Da quanto si è detto fin qui potrebbe sembrare che con il flexbox arrivi anche un modo alternativo per definire la larghezza di un elemento, alternativo cioè alla proprietà width. Di fatto è così, ma nulla toglie che invece che con flex, flex-grow e flex-basis, in un contesto flexbox, si possa continuare a usare la larghezza definita nel modo tradizionale. In certi casi, anzi, se si vuole un maggiore controllo sul modo in cui gli item occupano lo spazio, ciò può essere la scelta più corretta. Abbiamo operato in tal senso nella demo 10.
Abbiamo omesso del tutto di dichiarare la proprietà flex
. Così facendo, dato che il valore di default per flex-grow
è 0
, i box non sono flessibili, non vanno cioè ad assorbire lo spazio disponibile eventualmente presente nel contesto del contenitore.
La larghezza è stata fissata in percentuale, con un valore del 33.3%
. Ecco il codice completo per il componente:
.card-container {
display: flex;
display: -webkit-flex;
flex-direction: column;
-webkit-flex-direction: column;
width: 33.3%;
margin-top: 10px;
padding: 10px;
}
La griglia è comunque robusta, perfetta, con solo due possibili controindicazioni:
- se il numero di item della griglia non è un multiplo delle colonne della prima riga, si crea un'ultima riga sbilanciata, con uno spazio vuoto più o meno ampio;
- per adattare il layout al mobile è necessario fare ricorso alle media query, perché anche in questo caso non scatta il meccanismo del wrap.
Il problema degli item 'orfani' è facilmente risolvibile. Possiamo ad esempio selezionare l'ultimo elemento della griglia e applicare solo a questo una flex-grow
pari a 1
rendendolo flessibile:
.card-container:last-child {
flex-grow: 1;
-webkit-flex-grow: 1;
}
è quello che abbiamo fatto nella demo 11. La seconda riga della griglia è ora bilanciata, senza gap.
Oppure, sfruttando le formule sui selettori degli articoli di Clark e Pickering, possiamo selezionare gli ultimi due item della griglia, ottenendo una configurazione diversa (demo 11b):
.card-container:nth-child(3n+1):nth-last-child(-n+3),
.card-container:nth-child(3n+1):nth-last-child(-n+3) ~ .card-container {-webkit-flex-grow: 1;}
Quanto all'adattamento a varie larghezze, possiamo agire con le media query, come nella demo 12.
Se su larghezze superiori ai 760px la larghezza di ciascun box sarà pari al 33.3% costruendo una griglia di tre colonne, per larghezze inferiori possiamo aggiustare i valori realizzando una griglia su due colonne
@media all and (max-width: 760px) {
.card-container {width: 50%;}
}
oppure con una sola colonna quando larghezza massima è di 400px:
@media all and (max-width: 500px) {
.card-container {width: 100%;}
}
Modificare l'ordine dei box
Sempre in una prospettiva responsive, possiamo sfruttare un'altra potente funzionalità del flexbox: quella che ci permette di modificare l'ordine degli item al variare di scenari d'uso come la larghezza della finestra del browser, sovvertendo di fatto l'ordine in cui gli item stessi sono dichiarati nel codice HTML.
Nella demo 13, a larghezze superiori a 400px, i box della griglia sono visualizzati nello stesso ordine definito a livello HTML, tutto normale. Ma sotto i 400px, abbiamo rivoluzionato la disposizione intervenendo sulla proprietà order
, così:
@media all and (max-width: 400px) {
.first {
order: 4;
-webkit-order: 4;
}
.second {
order: 5;
-webkit-order: 5;
}
.third {
order: 2;
-webkit-order: 2;
}
.fourth {
order: 1;
-webkit-order: 1;
}
.fifth {
order: 3;
-webkit-order: 3;
}
}
Potete anche in questo verificare restringendo la finestra del browser dopo aver caricato la demo.
Saremmo potuti intervenire con order
a modificare altri aspetti del layout. Per esempio, mostrare sul mobile, a livello dei box che compongono la griglia, l'immagine sotto i contenuti testuali e prima del pulsante, ma avremmo dovuto per questo modificare il markup, per cui lo lasciamo come possibile esercizio a chi voglia sperimentare con questa straordinaria tecnica.
L'ultima demo presenta una versione ottimizzata per il mobile anche del menu di navigazione e del form di ricerca. Per i dettagli rimandiamo al codice sorgente.