Flex: i layout CSS del futuro?

Articolo CSS Flex Layout - Testata - Roberto Mannelli per webhouseit.com
Tempo stimato di lettura: 7 minuti, 14 secondi
Pubblicato il 4 Febbraio 2015

Finalmente i CSS3 ci propongono flex, un sistema di gestione dei layout potente e flessibile, con tante luci e qualche ombra…

Procediamo con ordine

Chiunque abbia un po’ di esperienza con i CSS, sa bene quali sono i limiti ed i problemi imposti dalla tecnica del floating. D’altra parte il floating non era stato pensato per la gestione dei layout, ovvero non come sistema per cambiare posizione agli elementi, ma come sistema per “rimpiazzare” l’attributo align degli elementi <img>.

Quando i CSS hanno consentito di abbandonare le tabelle per la gestione dei layout, il float è diventato un male necessario, in quanto non esisteva un meccanismo pensato per consentire ad un designer di “giocare” con i box, spostandoli a piacimento per creare layout diversi, a prescindere dal markup di partenza.

Un passo avanti

A partire dai CSS 2.1, l’introduzione del display:table ha permesso un balzo in avanti, consentendo di utilizzare una visualizzazione in stile tabella per realizzare layout complessi ma senza il problema del clearing, tipico del float.

Anche il display:table presenta tuttavia alcuni limiti (di cui però non parlerò perché non rientra negli obiettivi di questo articolo).

Flexible Layout, la soluzione definitiva?

La genesi dei flex layout è piuttosto complicata: la prima versione risale addirittura al 2009 e da allora i flexible layout hanno cambiato pelle più volte.

Se le precedenti versioni erano promettenti ma acerbe (anche per problemi di prestazioni), quella attuale sembra decisamente migliorata, potente e discretamente veloce (anche se i table layout sembrano più veloci).

Siamo dunque di fronte alla soluzione definitiva al problema della gestione dei layout? Vediamo…

Iniziamo…

Il primo passo da compiere è quello di applicare al contenitore una regola con display: flex (erano rispettivamente display: box e display: flexbox nelle due precedenti versioni).

Tutti gli esempi che farò d’ora in poi in questo articolo verranno applicati a questo markup:

<div id="container">
	<aside id="news">NEWS</aside>
	<aside id="sponsor">SPONSOR</aside>
	<main id="content">CONTENT</main>
</div>

Al quale aggiungiamo un paio di righe di CSS (ometto per brevità le regole di formattazione pura e semplice, come caratteri, colori, ecc…)

#container > aside, #container > main {
	box-sizing: border-box;
	text-align: center
}

Questo è l’aspetto iniziale:

Articolo CSS Flex Layout - Aspetto iniziale - Roberto Mannelli per webhouseit.com

Aspetto iniziale

Il primo passo per iniziare ad usare i flexible layout sarà dunque:

#container {
	display: flex;
}

Risultato:

Articolo CSS Flex Layout - Primo passo - Roberto Mannelli per webhouseit.com

Primo passo

Per default i box non sfruttano lo spazio a disposizione, ma si limitano ad occupare lo spazio minimo indispensabile per rendere visibile il contenuto. Rimediamo subito utilizzando la proprietà flex-grow, che si aspetta un valore numerico che indica la porzione di spazio a disposizione.

Nell’esempio che segue, #sponsor avrà una dimensione doppia di #news, mentre #content una dimensione tripla sempre rispetto a #news. Trattandosi di un layout fluido, le dimensioni verranno ricalcolate in base alla dimensione del viewport.

#news {flex-grow: 1;}
#sponsor {flex-grow: 2;}
#content {flex-grow: 3;}

Risultato:

Articolo CSS Flex Layout - flex-grow - Roberto Mannelli per webhouseit.com

La proprietà flex-grow

Uno degli aspetti interessanti (ma non l’unico) dei flex sta nella possibilità di modificare molto facilmente l’ordine degli elementi:

#news {flex-grow: 1; order: 3;}
#sponsor {flex-grow: 2; order: 2;}
#content {flex-grow: 3; order: 1;}

Risultato:

Articolo CSS Flex Layout - flex-grow - Roberto Mannelli per webhouseit.com

La proprietà order

Facile, vero? 😉

Un’altra interessante proprietà consente invece di cambiare l’orientamento del flusso: si tratta di flex-direction, che può assumere i valori row, row-reverse, column, column-reverse.

Il valore row è il predefinito, mentre con il valore column i box verranno disposti in colonna anziché in riga, rispettando order e flex-grow espressi in precedenza (quest’ultimo a patto di aver specificato una height per il contenitore):

#container {
	display: flex;
	height: 400px;
	flex-direction: column;
}

Risultato:

Articolo CSS Flex Layout - flex-direction - Roberto Mannelli per webhouseit.com

La proprietà flex-direction

Gli altri due valori disponibili per la proprietà flex-direction consentono di invertire la direzione del flusso.

Layout a riga singola / multipla: flex-wrap

Un flex container, per default, cerca di mantenere tutti i suoi elementi figli in una singola riga. E’ tuttavia possibile decidere di modificare questo comportamento sfruttando la proprietà flex-wrap: vediamo come funziona…

Per cominciare, inseriamo la proprietà flex-wrap nella regola del selettore #container (flex-wrap si applica al contenitore flex). I valori possibili sono:

  • nowrap: è il valore di default ed impone che gli elementi figli rimangano su un’unica riga
  • wrap: gli elementi possono essere separati in più righe se necessario
  • wrap-reverse: gli elementi possono essere separati in più righe se necessario ed il loro ordine è invertito rispetto all’ordine originale
#container {
	display: flex;
	flex-wrap: wrap;
}

Aggiungiamo quindi due proprietà nella regola con il selettore che include tutti gli elementi figli del contenitore flex:

  • flex-grow: 1;
  • min-width: 300px;
#container > aside, #container > main {
	box-sizing: border-box;
	text-align: center;
	flex-grow: 1;
	min-width: 300px;
}
#news {order: 3;}
#sponsor {order: 2;}
#content {order: 1;}

Risultato:

  • Se la “larghezza utile” è pari o superiore ai 900px (3*300px), il layout si presenta in questo modo:
Articolo CSS Flex Layout - flex-wrap - Roberto Mannelli per webhouseit.com

La proprietà flex-wrap

  • Se la “larghezza utile” scende sotto i 900px (3*300px), il layout si presenta in questo modo:
Articolo CSS Flex Layout - flex-wrap - Roberto Mannelli per webhouseit.com

La proprietà flex-wrap

Suggerimento: Questo è solo uno dei modi per sfruttare flex-wrap per ottenere la “suddivisione” degli elementi in più righe… prova, ad esempio, a sostituire flex-grow: 1 con width: 33%.

Distribuzione degli elementi in una riga: justify-content

Supponiamo adesso di dover posizionare elementi a dimensione fissa all’interno di un contenitore con dimensione superiore o addirittura variabile: la proprietà justify-content ci consente di scegliere come distribuire gli elementi figli. I valori ammessi sono:

  • flex-start: è il valore di default e posiziona gli elementi a partire da sinistra, mantenendoli ravvicinati
  • flex-end: posiziona gli elementi a partire da destra, mantenendoli ravvicinati
  • center: posiziona gli elementi al centro, mantenendoli ravvicinati
  • space-between: il primo elemento viene posizionato a sinistra, l’ultimo a destra e lo spazio residuo (differenza tra la larghezza del contenitore e la somma delle larghezze degli elementi figli) viene distribuito tra gli altri elementi
  • space-around: lo spazio residuo viene diviso per il numero di margini (n. di elementi * 2), quindi applicato ad ogni margine

Esempi:

#container {
	display: flex;
	justify-content: space-between;
}
#container > * {
	box-sizing: border-box;
	text-align: center
}
#news {width: 25%; order: 3;}
#sponsor {width: 25%; order: 2;}
#content {width: 25%; order: 1;}

Risultato:

Articolo CSS Flex Layout - justify-content - Roberto Mannelli per webhouseit.com

La proprietà justify-content

Sostituiamo adesso justify-content: space-between con justify-content: space-around

Risultato:

Articolo CSS Flex Layout - justify-content - Roberto Mannelli per webhouseit.com

La proprietà justify-content

Posizionamento verticale degli elementi: align-items

Se gli elementi figli di un contenitore flex hanno altezze diverse tra loro e comunque inferiori a quelle del contenitore, la proprietà align-items (da applicare al contenitore) ci permette di stabilire il posizionamento degli elementi.

I valori ammessi sono:

  • stretch: è il valore di default ed impone lo stretch verticale degli elementi per fare in modo che l’altezza sia uguale a quella del contenitore
  • flex-start: gli elementi vengono allineati al bordo superiore del contenitore. L’eventuale spazio residuo rimarrà sotto agli elementi
  • flex-end: gli elementi vengono allineati al bordo inferiore del contenitore. L’eventuale spazio residuo rimarrà sopra agli elementi
  • center: gli elementi verranno allineati verticalmente al centro del contenitore
  • baseline: gli elementi verranno allineati sulla linea di base del testo contenuto in essi
#container {
	width: 100%;
	height: 100px;
	border: 1px solid #000;
	display: flex; 
	align-items: center; /*allineamento verticale */
}
#container > * {
	box-sizing: border-box;
	text-align: center
}
#news {flex-grow: 1; order: 3; line-height: 40px;}
#sponsor {flex-grow: 2; order: 2; line-height: 80px;}
#content {flex-grow: 4; order: 1; line-height: 60px;}

Risultato:

Articolo CSS Flex Layout - align-items - Roberto Mannelli per webhouseit.com

La proprietà align-items

Sostituiamo align-items: center con align-items: flex-start

Articolo CSS Flex Layout -align-items - Roberto Mannelli per webhouseit.com

La proprietà align-items

Adesso puoi procedere in autonomia, testando i risultati con gli altri valori.

Conclusioni

Abbiamo esplorato quasi tutte le proprietà che ruotano intorno ai flex layout e ritengo che quanto visto sia più che sufficiente per intuire le potenzialità dello strumento e con un po’ di creatività e di fantasia le possibilità sono davvero notevoli.

A mio modo di vedere può rappresentare la “luce in fondo al tunnel”, dopo anni di layout creati esclusivamente con il float (o quasi…).

Ma è tutto oro ciò che luccica? Purtroppo, come al solito, no… 🙁

Il problema principale dei flex layout è lo scarso supporto da parte dei browser meno recenti (come sempre il problema è rappresentato principalmente da IE e dalla frammentazione delle sue installazioni).

Dato che il supporto da parte dei browser cambia costantemente, ti consiglio di dare un’occhiata qui: http://caniuse.com/#search=flex

Un altro problema è secondo me dato dalla scarsa uniformità dei nomi delle proprietà e dalla complessità generale del sistema, la cui curva di apprendimento è piuttosto ripida.

E tu cosa ne pensi?

Se vuoi saperne di più: http://www.w3.org/TR/css3-flexbox/

Shares