Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Colonne affiancate con altezza uguale

Con flexbox affiancare colonne della stessa altezza diventa più immediato, non più una soluzione basata su hack ma fondata sulle funzionalità native dei CSS
Con flexbox affiancare colonne della stessa altezza diventa più immediato, non più una soluzione basata su hack ma fondata sulle funzionalità native dei CSS
Link copiato negli appunti

Un altro scenario frequente e reale in cui il flexbox si rivela la soluzione perfetta è quello dei layout in cui si abbia la necessità di avere colonne affiancate con altezza uguale a prescindere dai contenuti ospitati nelle colonne. È un problema annoso per il quale sono state trovate nel corso del tempo soluzioni ingegnose e robuste, sia basate sui soli CSS sia implementate via Javascript come nel componente Equalizer del framework Foundation. Con flexbox tutto diventa più immediato, una soluzione non basata su hack ma semplicemente fondata sulle funzionalità native di questa parte dei CSS.

Di default, infatti, quando si creano colonne affiancate disposte su una riga all'interno di un contenitore flessibile, il valore della proprietà align-items è impostato sul valore stretch, quello che fa sì che le colonne si estendano, appunto, per occupare tutto lo spazio disponibile verticalmente. L'altezza di ciascuna colonna viene automaticamente calcolata per essere uguale a quella della colonna più lunga perché ha più contenuto.

Nell'analisi delle demo di questa sezione possiamo dunque partire da un esempio in cui per creare il layout sono stati usati i float. Senza intervenire con altre tecniche per estendere le colonne, ci ritroviamo in questa situazione:

Figura 7 - Colonne ad altezza disuguale (click per ingrandire)


screenshot

Vediamo come abbiamo usato il flexbox per ottenere il risultato della demo 7, illustrato dalla seguente schermata:

Figura 8 - Colonne ad altezza uguale con flexbox

screenshot

I tre box (colonne) della semplice griglia sono contenuti in un elemento con classe .cards:

.cards {
display: flex;
display: -webkit-flex;
flex-flow: row nowrap;
-webkit-flex-flow: row nowrap;
align-items: stretch;
-webkit-align-items: stretch;
justify-content: space-between;
-webkit-justify-content: space-between;
margin-top: 10px;
}

Lo dichiariamo display: flex. Impostiamo la proprietà flex-flow con i valori row (gli elementi si dispongono su una riga) e nowrap (impediamo agli elementi di disporsi su più righe).

Abbiamo anche specificato il valore stretch per align-items, giusto a fini didattici, perché come si accennava è il valore di default. Infine, facciamo sì che gli item si dispongano orizzontalmente creando una spaziatura proporzionale tra di loro (justify-content: space-between).

Fatto. I box contenuti in .cards-container avranno altezza uguale con queste semplici istruzioni. La chiave, ribadiamo, è la proprietà align-items: stretch.

Il lavoro non è però completo. Vogliamo anche che il pulsante posto in basso sia ancorato sempre sul fondo del box. In questo caso dobbiamo lavorare sui singoli componenti della griglia e non semplicemente sul loro contenitore.

Passiamo dunque ai box che compongono la griglia. Sono definiti da un div con classe .card-container:

.card-container {
display: flex;
display: -webkit-flex;
flex-direction: column;
-webkit-flex-direction: column;
width: 33.3%;
padding: 10px;
}

Dato che vogliamo che gli elementi che contiene siano flessibili, dichiariamo anche per esso display: flex. E poiché tali elementi si disporranno verticalmente, impostiamo flex-direction su column invece che row.

La larghezza (width) e il padding servono a dare una dimensione orizzontale e a spaziare i tre box.

Ciascun box è poi suddiviso in due blocchi. Il primo ospita un'immagine flessibile che si adatta automaticamente alla larghezza del suo contenitore. La tecnica è quella classica con max-width: 100% che abbiamo visto all'opera nell'articolo Immagini flessibili e nella guida al responsive design. Ecco la regola per l'immagine, per il div .card-image non è necessario specificare alcuna regola:

.card-image img {
display: block;
height: auto;
margin: 0 auto;
max-width: 100%;
width: 100%;
}

Il componente del box più problematico è quello con il contenuto testuale, identificato dalla classe card-content. Dato che questo contenuto è variabile e che da esso dipende l'altezza reale del div che contiene il testo e il pulsante, quest'ultimo verrà ovviamente a collocarsi ad altezze diverse, come illustrato da questo screenshot. Abbiamo sì altezze uguali per i box, ma il pulsante non è ancorato sul fondo.

Figura 9 - Pulsante ad altezze diverse

screenshot

Per risolvere questo problema di allineamento del pulsante la soluzione immediata sarebbe ricorrere, come nel caso già visto del form di ricerca, al margine automatico, applicato a margin-top visto che vogliamo un allineamento sul lato inferiore. La cosa, da sola, non è però sufficiente, perché quando operiamo in verticale, avendo come riferimento l'altezza e non la larghezza, è necessario fornire un riferimento, un contesto di posizionamento, uno spazio in verticale rispetto al quale il pulsante possa collocarsi sul fondo del suo contenitore. Insieme al margine automatico, dunque, dovremo assegnare al div .card-content anche un flex: 1. Con questa dichiarazione diciamo: cresci ed espanditi fino ad occupare tutto lo spazio disponibile.

Ecco la regola CSS che usiamo per impostare il div:

.card-content {
display: flex;
display: -webkit-flex;
flex-direction: column;
-webkit-flex-direction: column;
padding: 10px 0;
}
.mgtop-auto {margin-top: auto;}

Semplificando molto, abbiamo fatto questo:

  • il div con l'immagine non è flessibile, ha flex-grow impostato su 0, per cui occuperà verticalmente lo spazio dettato dal suo contenuto;
  • il div con il contenuto testuale, invece, ha, tramite la proprietà flex, un flex-grow pari a 1, che lo fa diventare flessibile per fargli occupare tutto lo spazio disponibile; ciò crea anche un contesto per l'altezza che ci consente di applicare l'allineamento in basso con margin-top: auto;.

Il problema delle colonne uguali in altezza è risolto in modo elegante e semplice, naturale, perché flexbox è fatto esattamente per questo.

Ti consigliamo anche