facebook

Blog

Resta aggiornato

Vediamo quali sono le Best Practices nell’uso di CSS Grid e che fine farà Flexbox
CSS Grid: Best Practices
mercoledì 11 Dicembre 2019

Negli esempi precedenti, abbiamo visto come costruire i layout prendendo come riferimento i valori numerici assegnati alle linee. Adesso vedremo alcune Best Practices per semplificare il lavoro.
Il primo metodo consiste nel definire dei nomi da assegnare ai template delle colonne ed eventualmente alle righe:

.container {
display: grid;
grid-template-rows: 100px 50px 300px 80px;
grid-template-columns: repeat(3, [container-start] 1fr) 300px [container-end];
}

In questo modo, invece dei numeri possiamo utilizzare i nomi che abbiamo stabilito:

.header {
    grid-column: container-start / container-end;
}
.navbar {
    grid-column: container-start / container-end;
}
.footer {
    grid-column: container-start / container-end;
}

L’ultimo approccio prevede l’assegnazione di nomi alle aree: è un metodo a mio parere non molto flessibile, che poco si adatta ai progetti più grandi.
Attraverso la proprietà:

grid-template-areas

assegnerò i nomi alle aree che, come abbiamo visto in precedenza, sono costituite da gruppi di celle. Ad esempio, per definire il template per .header, nel selettore .container assegnerò il nome dell’area raggruppando quattro celle:

grid-template-areas: "header header header header"

Invece, richiamerò il template dell’area dedicata al selettore di .header attraverso la proprietà:

grid-area: header;

Ecco l’esempio completo:

.container {
    display: grid;
    grid-template-rows: 100px 50px 300px 80px;
    grid-template-columns: repeat(3, 1fr) 300px;
    grid-template-areas: "header header header header"
                         "navbar navbar navbar navbar"
                         "content content content sidebar"
                         "footer footer footer footer";
}
.header {
    grid-area: header;
}
.navbar {
    grid-area: navbar;
}
.content {
    grid-area: content;
}
.sidebar {
    grid-area: sidebar;
}
.footer {
    grid-area: footer;
}

Come adattare la griglia ai dispositivi mobili senza ricorrere alle media queries

Partiamo dal seguente markup e dal suo relativo foglio di stile:

.container {
    display: grid;
    grid-template-rows: 100px 50px auto 80px;
    grid-template-columns: repeat(3, 1fr) 300px;
}
.header {
    grid-column: 1 / -1;
}
.navbar {
    grid-column: 1 / -1;
}
.content {
    grid-column: 1 / -2;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: 125px;
    gap: 20px;
  
    &__item {
        background: orange;
        padding: 10px;
    }
}
.footer {
    grid-column: 1 / -1;
}

Da notare che abbiamo assegnato il valore auto per definire l’altezza della riga contenente il .content e la .sidebar:

grid-template-rows: 100px 50px auto 80px;

Questo espediente farà in modo che l’altezza del blocco si possa adattare alla quantità di contenuti presenti in esso.
L’obiettivo sarà quello di posizionare la .sidebar sotto al .content nella versione mobile, e di far posizionare i blocchi contenuti da .content in base alla larghezza.
Modifichiamo adesso la proprietà grid-template-columns.
Non specificheremo più la quantità di colonne (3), ma utilizzeremo la proprietà auto-fit che genererà in automatico le tracce in base allo spazio disponibile:

grid-template-columns: repeat(3, 1fr) 300px;
grid-template-columns: repeat(auto-fit, 1fr) 300px;

Inoltre, grazie alla funzione minmax, specificheremo una larghezza minima (300px) e una massima (1fr): quindi, sui display più piccoli la larghezza della colonna sarà di 300px, mentre su quelli più grandi sarà di 1fr.

/* grid-template-columns: repeat(auto-fit, 1fr) 300px; */
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));

Abbiamo inoltre rinunciato alla definizione della larghezza fissa per la .sidebar, che di fatto conserverà la posizione, perché in precedenza avevamo stabilito che il .content avrebbe dovuto occupare lo spazio compreso tra la linea 1 e la -2:

.content {
    grid-column: 1 / -2;
}

Per quanto riguarda invece i blocchi contenuti in .content, andremo anche qui ad eliminare il numero specifico di colonne in favore della funzione auto-fit e della definizione di una larghezza minima e una massima:

/* grid-template-columns: repeat(3, 1fr); */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));

Il codice definitivo sarà quindi il seguente:

.container {
    display: grid;
    grid-template-rows: 100px 50px auto 80px;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  
    &>* {
        color: #5c5c5c;
        padding: 10px;
    }
}
.header {
    grid-column: 1 / -1;
    background: coral;
}
.navbar {
    grid-column: 1 / -1;
    background: brown;
}
.content {
    grid-column: 1 / -2;
    background: gray;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    grid-auto-rows: 125px;
    gap: 20px;
  
    &__item {
        background: orange;
        color: #ffffff;
        padding: 10px;
    }
}
.sidebar {
    background: orangered;
}
.footer {
    grid-column: 1 / -1;
    background: brown;
}

Questo è il risultato che abbiamo ottenuto:

Flexbox vs CSS Grid

La domanda che spesso sorge spontanea è: ma adesso che fine farà Flexbox?
In realtà, i due moduli possono essere tranquillamente utilizzati in combo:

  • Con CSS Grid realizzeremo tutta la struttura portante del layout e andremo invece a definire la UI di elementi che richiedono la gestione simultanea del posizionamento sui due assi x e y;
  • Flexbox, invece, è più adatto alla gestione di un singolo asse per volta (ad esempio: menù di navigazione, liste verticali o orizzontali, ecc)

Per approfondire la questione, vi lascio il link della specifica w3c, dove proprio nell’introduzione si parla della differenza tra i due moduli.

In conclusione

Ci sarebbe ovviamente tanto altro da vedere, perché la specifica CSS Grid è molto vasta e in continua evoluzione, ma con le tecniche che abbiamo analizzato in questa serie di articoli saremo già in grado di realizzare dei layout grazie a CSS Grid!