Feedback necessario: come dobbiamo definire la disposizione a mattoni CSS?

Ian Kilpatrick
Ian Kilpatrick
Tab Atkins-Bittner
Tab Atkins-Bittner

Data di pubblicazione: 19 settembre 2024

Il gruppo di lavoro CSS ha combinato le due proposte di organizzazione in riquadri CSS in una bozza di specifica. Il gruppo spera che questo semplifichi il confronto tra i due e la presa di una decisione definitiva. Il team di Chrome ritiene ancora che una sintassi di muratura separata sia il modo migliore per procedere. Anche se il problema di rendimento più grande menzionato nel nostro post precedente è stato risolto, rimangono dubbi sulla sintassi, sui valori iniziali e sulla facilità di apprendimento di una versione combinata con la griglia.

Tuttavia, per verificare le nostre ipotesi, abbiamo esaminato alcuni esempi per mostrare come la disposizione a riquadri funzionerebbe con ogni versione. Dai un'occhiata agli esempi in questo post e inviaci il tuo feedback, in modo che possiamo prendere una decisione e procedere con questa funzionalità.

Questo post non copre tutti i possibili casi d'uso, ma è chiaro che la separazione della disposizione a mattoni dal layout a griglia non comporterà la mancanza di funzionalità. In realtà, potrebbe essere vero il contrario. Come vedrai in questo post, la versione display: masonry offre nuove opportunità e una sintassi più semplice. Inoltre, molti sviluppatori hanno espresso dubbi sul potenziale riordinamento degli elementi con la disposizione a riquadri che potrebbe causare problemi di accessibilità. Questo problema verrà risolto anche per entrambe le versioni della sintassi, tramite la proprietà reading-flow proposta.

Un layout di base con disposizione a mattoni

Questo è il layout che la maggior parte delle persone immagina quando pensa alla muratura. Gli elementi vengono visualizzati in righe e, dopo aver inserito la prima riga, gli elementi successivi si inseriscono nello spazio lasciato dagli elementi più brevi.

Un layout con colonne, in cui gli elementi che le riempiono non presentano spazi.
In questo layout vengono definite le colonne, quindi gli elementi vengono inseriti in modo da formare una disposizione a mattoni anziché in righe rigide.

Con display: masonry

Per creare un layout a mattoncini, utilizza il valore masonry per la proprietà display. In questo modo viene creato un layout a riquadri con canali di colonne che definisci (o sono definiti dai contenuti) e una disposizione a riquadri nell'altro asse. Il primo elemento viene visualizzato all'inizio del blocco e in linea (quindi in alto a sinistra in inglese) e gli elementi vengono disposti in direzione in linea.

Per definire le tracce, utilizza masonry-template-tracks con i valori della traccia come utilizzati nel layout a griglia CSS.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(3, 1fr);
  gap: 10px;
}

Con display: grid

Per creare un layout a mattoncini, crea innanzitutto un layout a griglia utilizzando il valore grid per la proprietà display. Definisci le colonne con la proprietà grid-template-columns, quindi assegna a grid-template-rows il valore masonry.

Verrà creato un layout come previsto con gli elementi della griglia posizionati automaticamente, tuttavia gli elementi di ogni riga utilizzano un layout a mattoncini e si riorganizzano per occupare lo spazio lasciato dagli elementi più piccoli nella riga precedente.

.masonry {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: masonry;
  gap: 10px;
}

Aspetti da considerare tra le due opzioni

Una differenza significativa tra questi metodi è che con la versione display: masonry viene visualizzato un layout a riquadri anche se non specifichi alcun canale con masonry-template-tracks. Pertanto, display: masonry potrebbe essere tutto ciò che ti serve. Questo perché il valore iniziale di masonry-template-tracks è repeat(auto-areas, auto). Il layout crea tutti i canali con dimensioni automatiche che possono essere inseriti nel contenitore.

Flusso invertito con muratura

La specifica include modi per modificare la direzione del flusso della muratura. Ad esempio, puoi modificare il flusso da visualizzare dal blocco in alto.

Un layout con colonne, gli elementi che riempiono le colonne lo fanno dalla parte inferiore del layout.
In questo layout vengono definite le colonne, quindi gli elementi vengono inseriti in modo da formare una serie di elementi consecutivi a partire dalla fine del blocco.

Con display: masonry

Crea un layout a riquadri con display: masonry, quindi utilizza masonry-direction con un valore di column-reverse.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(3, 1fr);
  masonry-direction: column-reverse;
}

Con display: grid

Crea un layout a riquadri con display: grid e grid-template-rows: masonry. Quindi, utilizza la proprietà grid-auto-flow con un nuovo valore row-reverse per impostare il layout degli elementi dall'estremità del blocco del contenitore della griglia.

.masonry {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: masonry;
  grid-auto-flow: row-reverse;
}

Aspetti da considerare tra le due opzioni

La versione display: masonry è molto simile al funzionamento di flexbox. Modifica la direzione di scorrimento delle colonne utilizzando la proprietà masonry-direction con un valore di column-reverse.

La versione CSS grid utilizza grid-auto-flow. Come attualmente definito,grid-auto-flow: row-reverse e grid-auto-flow: column-reverse avrebbero lo stesso effetto. Questo potrebbe creare confusione, perché potresti aspettarti che facciano qualcosa di diverso.

Muratura per righe

Puoi anche cambiare direzione per definire le righe.

Un layout con righe, in cui gli elementi che le riempiono non presentano spazi.
In questo layout vengono definite le righe, quindi gli elementi vengono inseriti in modo da formare una griglia anziché colonne rigide.

Con display: masonry

Crea un layout a riquadri con display: masonry, quindi imposta il valore di masonry-direction su row. A meno che tu non voglia che le righe abbiano un blocco specifico le dimensioni, non è necessario specificare le dimensioni dei canali poiché il valore predefinito è auto, quindi le dimensioni dei canali verranno adattate ai contenuti che contengono.

.masonry {
  display: masonry;
  masonry-direction: row;
}

Con display: grid

.masonry {
  display: grid;
  grid-template-columns: masonry;
  grid-template-rows: repeat(3, 1fr);
}

Aspetti da considerare tra le due opzioni

Come per il flusso inverso, la modifica della versione display: masonry dalle colonne alle righe comporta la modifica del valore di masonry-direction. Con la versione a griglia, dovrai cambiare i valori delle proprietà grid-template-columns e grid-template-rows. In alternativa, se utilizzi la rappresentazione abbreviata, modifica l'ordine della sintassi.

In entrambi gli esempi di flusso di passaggio, la versione display: masonry sembra più intuitiva. Esiste una singola proprietà che controlla il flussomasonry-direction, che può assumere uno dei seguenti valori:

  • row
  • column
  • row-reverse
  • column-reverse

Aggiungi quindi le informazioni sulle dimensioni necessarie a masonry-template-tracks, assumendo che il valore predefinito automatico non sia quello che ti serve.

Con la griglia, per eseguire la direzione inversa devi utilizzare la proprietà grid-auto-flow e per eseguire la disposizione a mattoncini delle righe devi modificare il valore delle proprietà grid-template-*. Inoltre, nella sintassi attuale della griglia non è possibile lasciare undefined il valore dell'asse della griglia. Devi sempre specificare proprietà grid-template-* sull'asse che non ha un valore masonry.

Posizionare gli elementi

In entrambe le versioni puoi posizionare esplicitamente gli elementi utilizzando il posizionamento basato su riga che conosci dal layout a griglia. In entrambe le versioni puoi collocare gli elementi solo nell'asse della griglia, ovvero l'asse con le tracce predefinite. Non puoi posizionare gli elementi sull'asse che genera il layout a riquadri.

Con display: masonry

Il seguente CSS definisce un layout a mattoncini con quattro colonne. L'asse della griglia è quindi costituito dalle colonne. L'elemento con una classe a viene inserito dalla riga della prima colonna alla riga della terza colonna, interessando due canali con le nuove proprietà masonry-track-*. Può anche essere definito come una scorciatoia per masonry-track: 1 / 3;.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(4, 1fr);
}

.a {
  masonry-track-start: 1;
  masonry-track-end: 3;
}

Con display: grid

Il seguente CSS definisce un layout a mattoncini con quattro colonne. L'asse della griglia è quindi costituito dalle colonne. L'elemento con una classe a viene inserito dalla riga della prima colonna alla riga della terza colonna, interessando due tracce con le proprietà grid-column-*. Può anche essere definito come una scorciatoia per grid-column: 1 / 3;.

Se l'asse della griglia è colonne, le proprietà grid-row-* verranno ignorate, mentre se l'asse della griglia è righe, le proprietà grid-columns-* verranno ignorate.

.masonry {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

.a {
  grid-column-start: 1;
  grid-column-end: 3;
}

Puoi utilizzare le righe con nome con entrambe le sintassi. Gli esempi riportati di seguito mostrano una griglia con due righe di colonna denominate a.

Con display: masonry

Le righe con nome sono definite nel valore della traccia di masonry-template-tracks. L'elemento può essere inserito dopo qualsiasi riga denominata a.

.masonry {
  display: masonry;
  masonry-template-tracks: 100px [a] auto [a] auto 100px;
}

.item {
  masonry-track: a;
}

Con display: grid

Le righe con nome sono definite nel valore della traccia di grid-template-columns. L'elemento viene inserito dopo la prima riga denominata a. Se la proprietà grid-row è definita, verrà ignorata.

.masonry {
  display: grid;
  grid-template-columns: 100px [a] auto [a] auto 100px;
  grid-template-rows: masonry;
}

.item {
  grid-column: a;
  grid-row: a; /* ignored */
}

Puoi anche utilizzare aree denominate in entrambe le sintassi. Gli esempi seguenti mostrano una tabella con tre canali denominati "a", "b" e "c".

Con display: masonry

I canali sono denominati come il valore di masonry-template-areas. Poiché non sono definite dimensioni per i canali, per tutti e tre viene impostata la dimensione auto. L'elemento viene inserito nel canale "a".

.masonry {
  display: masonry;
  masonry-template-areas: "a b c";
}

.item {
  masonry-track: a;
}

Il funzionamento è lo stesso indipendentemente dal fatto che tu stia definendo righe o colonne; l'unica differenza è la proprietà masonry-direction.

Con display: grid

Per le colonne, la sintassi è essenzialmente identica. Analogamente, poiché non sono definite dimensioni per i canali, per tutti e tre viene utilizzata per impostazione predefinita la dimensione auto, ma devi comunque indicare esplicitamente che l'altro asse è in mattonella:

.masonry {
  display: grid;
  grid-template-areas: "a b c";
  grid-template-rows: masonry;
}

.item {
  grid-column: a;
}

Per righe, tuttavia, il valore deve essere scritto in modo diverso, perché grid-template-areas definisce in realtà un'area bidimensionale e ogni riga è scritta come una stringa separata:

.masonry {
  display: grid;
  grid-template-areas: "a" "b" "c"; /* Note the difference, each row is quoted. */
  grid-template-columns: masonry;
}

.item {
  grid-row: a;
}

Aspetti da considerare tra le due opzioni

Con qualsiasi posizionamento, la sintassi display: masonry funziona meglio quando si tratta di cambiare direzione. Poiché la proprietà masonry-track-* funziona in qualsiasi direzione sia l'asse della griglia, per cambiare direzione devi solo modificare il valore di masonry-direction. Con la versione a griglia, sono necessarie almeno proprietà ridondanti per attivare il passaggio. Tuttavia, consulta gli esempi precedenti per altri modi in cui cambiare direzione è più complicato con la versione della griglia.

Abbreviazioni

In questo post sono state utilizzate le versioni lunghe per chiarire meglio quali proprietà sono in uso, ma sia le versioni display: masonry che display: grid possono essere definite utilizzando le versioni abbreviate.

Con display: masonry

La scorciatoia display: masonry utilizza la parola chiave masonry. Per creare il layout di base della disposizione a mattoni, utilizza il seguente CSS:

.masonry {
  display: masonry;
  masonry: repeat(3, 1fr);
}

Per creare un semplice layout a riquadri basato su righe:

.masonry {
  display: masonry;
  masonry: row;
}

Per definire tracce e un layout basato su righe con la notazione abbreviata:

.masonry {
  display: masonry;
  masonry: repeat(3, 1fr) row;
}

Con display: grid

Per creare il layout di base con disposizione a mattoni utilizzando la notazione grid.

.masonry {
  display: grid;
  grid: masonry / repeat(3, 1fr);
}

Per creare un semplice layout a riquadri basato su righe:

.masonry {
  display: grid;
  grid: repeat(3, auto) / masonry;
}

In esempi più complessi, poiché la sintassi complessiva di display:masonry è più semplice, è possibile raggruppare più proprietà nella rappresentazione abbreviata senza che diventi eccessivamente complessa.

Ad esempio, immagina di creare tre colonne denominate "a", "b" e "c", compilate dall'alto verso il basso.

Con display:masonry

In display: masonry, tutti e tre questi valori possono essere impostati insieme nella notazione abbreviata:

.masonry {
  display: masonry;
  masonry: column-reverse "a b c";
}

Poiché le dimensioni sono automatiche, non è necessario specificarle, ma se preferisci una dimensione specifica, puoi aggiungerla. Ad esempio: masonry: column-reverse 50px 100px 200px "a b c";.

Inoltre, ogni componente può essere riordinato liberamente; non c'è un ordine specifico da ricordare. Se invece vuoi utilizzare le righe, non devi fare altro che sostituire column-reverse con row o row-reverse. Il resto della sintassi rimane invariato.

Con display: grid

In display: grid, questi tre aspetti devono essere impostati separatamente:

.masonry {
  display: grid;
  grid-template-rows: masonry;
  grid-template-areas: "a b c";
  grid-auto-flow: wrap-reverse;
}

Come nell'esempio di disposizione a mattoni, tutte le colonne avranno la dimensione auto, ma se volevi fornire dimensioni esplicite, puoi farlo:

.masonry {
  display: grid;
  grid: masonry / 50px 100px 200px;
  grid-template-areas: "a b c";
  grid-auto-flow: wrap-reverse;
}

In alternativa, se vuoi utilizzare "grid" per impostare contemporaneamente le dimensioni e i nomi delle aree:

.masonry {
  display: grid;
  grid: "a b c" masonry / 50px 100px 200px;
  grid-auto-flow: wrap-reverse;
}

In entrambi gli esempi, l'ordine è strettamente necessario e diverso se invece volevi le righe. Ad esempio, la modifica in righe ha il seguente aspetto:

.masonry {
  display: grid;
  grid: 50px 100px 200px / masonry;
  grid-template-areas: "a" "b" "c";
}

In alternativa, per riassumerli tutti in una sola abbreviazione:

.masonry {
  display: grid;
  grid: "a" 50px "b" 100px "c"  200px / masonry;
}

Aspetti da considerare tra le due opzioni

È probabile che la rappresentazione simbolica display: masonry venga ampiamente utilizzata, dato che è relativamente semplice. In molti casi, per un layout "standard" con disposizione a mattoni, dovrai solo impostare le definizioni dei canali. Tutti gli altri valori possono assumere il valore predefinito.

La versione display: grid utilizza la rappresentazione abbreviata grid esistente, che è abbastanza complessa e, secondo la nostra esperienza, è meno utilizzata dagli sviluppatori. Come mostrato negli esempi precedenti, anche se utilizzato per layout di tipo galleria semplice, è necessario prestare attenzione all'impostazione dell'ordine dei valori.

Altre considerazioni

Questo post esamina alcuni casi d'uso comuni oggi, ma non sappiamo cosa potrebbe riservarci il futuro per la griglia o la disposizione a riquadri. Un argomento importante a favore dell'utilizzo della sintassi distinta per display: masonry è che consente di differenziare le due in futuro. In particolare, con i valori iniziali, come quelli per masonry-template-tracks, potrebbe essere utile fare qualcosa di diverso in una disposizione a riquadri rispetto a una griglia. Se optiamo per la versione display: grid, non possiamo cambiare le impostazioni predefinite della griglia, il che potrebbe limitare le azioni che potremmo voler intraprendere in futuro.

In questi esempi, puoi vedere i punti in cui il browser deve ignorare le proprietà valide in griglia se utilizzi la disposizione a mattoni. Ad esempio grid-template-areas, dove la maggior parte dei valori viene eliminata perché definisce un layout a griglia bidimensionale, nella disposizione a mattonella viene definita solo una direzione.

Fornisci il tuo feedback

Dai un'occhiata a questi esempi e anche alla bozza della specifica che mostra ciascuna versione accanto all'altra. Facci sapere la tua opinione commentando il Issue 9041 o, se preferisci, scrivi un post sul tuo blog o sui social media e non esitare a contattarci su X o LinkedIn.