Una proposta alternativa per la muratura CSS

Il team di Chrome è interessato a vedere un'implementazione di layout di tipo "masonry" sul web. Tuttavia, riteniamo che implementarlo come parte della specifica CSS Grid come proposto nel recente post di WebKit sarebbe un errore. Inoltre, riteniamo che il post di WebKit abbia discusso contro una versione della disposizione a riquadri che nessuno stava proponendo.

Pertanto, lo scopo di questo post è spiegare perché in Chrome abbiamo dei dubbi sull'implementazione della disposizione a mattoni all'interno della specifica CSS Grid Layout e chiarire esattamente cosa consente la proposta alternativa. In breve:

  • Il team di Chrome è molto interessato a sbloccare la disposizione a riquadri, perché sappiamo che è una funzionalità richiesta dagli sviluppatori.
  • L'aggiunta della disposizione a mattoni alla specifica della griglia è problematica per motivi diversi dal fatto che tu ritenga che la disposizione a mattoni sia una griglia o meno.
  • La definizione della disposizione a mattoni al di fuori della specifica della griglia non impedisce l'utilizzo di più dimensioni di canale per la disposizione a mattoni o l'uso di proprietà come allineamento o spaziature o di qualsiasi altra funzionalità utilizzata nel layout della griglia.

La muratura deve far parte della griglia?

Il team di Chrome ritiene che la disposizione a mattoni debba essere un metodo di layout distinto, definito utilizzando display: masonry (o un'altra parola chiave se si deciderà di scegliere un nome migliore). Più avanti in questo post, puoi vedere alcuni esempi di come potrebbe essere il codice.

Esistono due motivi correlati per cui riteniamo che la disposizione a mattoni sia meglio definita al di fuori del layout a griglia: i potenziali problemi di prestazioni del layout e il fatto che sia la disposizione a mattoni sia la griglia hanno funzionalità che hanno senso in un metodo di layout, ma non nell'altro.

Prestazioni

La griglia e la disposizione a mattoni sono opposte in termini di gestione delle dimensioni e del posizionamento da parte del browser. Quando viene impostata una griglia, tutti gli elementi vengono posizionati prima del layout e il browser sa esattamente cosa contiene ogni traccia. In questo modo è possibile eseguire il complesso dimensionamento intrinseco così utile nella griglia. Con la disposizione a mattonella, gli elementi vengono posizionati come sono disposti e il browser non sa quanti sono in ogni traccia. Questo non è un problema con tutti i canali con dimensioni intrinseche o con tutti i canali con dimensioni fisse, ma lo è se combini canali con dimensioni fisse e canali con dimensioni intrinseche. Per ovviare al problema, il browser deve eseguire un passaggio di pre-layout per disporre ogni elemento in tutti i modi possibili per ottenere le misurazioni. Con una griglia di grandi dimensioni, questo potrebbe contribuire a problemi di prestazioni del layout.

Pertanto, se hai un layout a riquadri con una definizione di canale digrid-template-columns: 200px auto 200px, un'operazione molto comune in griglia, inizi a riscontrare problemi. Questi problemi diventano esponenziali quando aggiungi reti secondarie.

Si potrebbe sostenere che la maggior parte degli utenti non riscontrerà questo problema, ma sappiamo già che molti utenti hanno griglie molto grandi. Non vogliamo rilasciare un prodotto con limitazioni di utilizzo, quando esiste un approccio alternativo.

Che cosa facciamo per gli elementi che non hanno senso in ogni metodo di layout?

Quando flexbox e grid sono diventati parte del CSS, gli sviluppatori spesso hanno ritenuto che il loro comportamento fosse incoerente. L'incongruenza riscontrata era dovuta a presupposti consolidati sul funzionamento del layout, basato sul layout dei blocchi. Nel tempo, gli sviluppatori hanno iniziato a comprendere i contesti di formattazione. Quando passiamo a un contesto di formattazione flessibile o a griglia, alcune cose si comportano in modo diverso. Ad esempio, sai che quando utilizzi flexbox, non tutti i metodi di allineamento sono disponibili, perché flexbox è unidimensionale.

L'unione della disposizione a mattoni in una griglia rompe questo chiaro collegamento tra il contesto di formattazione e la disponibilità di elementi come le proprietà di allineamento, che sono definite nella specifica Allineamento della casella in base al contesto di formattazione.

Se decidiamo di risolvere il problema di prestazioni descritto in precedenza rendendo illegali le definizioni di canali intrinseci e fissi misti nella disposizione a riquadri, dovrai ricordare che uno schema molto comune per i layout della griglia non funziona per la disposizione a riquadri.

Esistono anche pattern che avrebbero senso nella disposizione a mattoni, ad esempiogrid-template-columns: repeat(auto-fill, max-content), perché non hai vincoli incrociati, ma devono rimanere non validi nella griglia. Di seguito è riportato un elenco di proprietà che ci aspettiamo si comportino in modo diverso o abbiano valori validi diversi.

  • grid-template-areas: in muratura puoi specificare solo la riga iniziale in direzione non muraria.
  • grid-template: la scorciatoia dovrebbe tenere conto di tutte le differenze.
  • Monitora i valori di dimensione per grid-template-columns e grid-template-rows a causa delle differenze nei valori legali.
  • grid-auto-flow non si applica alla disposizione a mattoni e masonry-auto-flow non si applica alla griglia. La loro unione causerebbe problemi di elementi non validi a causa del metodo di layout in uso.
  • La griglia ha quattro proprietà di posizionamento (grid-column-start e così via), mentre la disposizione a riquadri ne ha solo due.
  • Grid può utilizzare tutte e sei le proprietà justify-* e align-*, ma Masonry utilizza solo un sottoinsieme come flexbox.

Sarà inoltre necessario specificare cosa accade in tutti i nuovi casi di errore causati dagli sviluppatori che utilizzano un valore non valido in griglia con disposizione a riquadri o griglia senza disposizione a riquadri. Ad esempio, è valido utilizzare grid-template-columns: masonry o grid-template-rows: masonry ma non entrambi contemporaneamente. Che cosa succede se li usi entrambi contemporaneamente? Questi dettagli devono essere specificati in modo che tutti i browser svolgano la stessa operazione.

Tutto ciò diventa complicato dal punto di vista delle specifiche, ora e in futuro. Dovremo assicurarci che tutto tenga conto della muratura e se funziona o meno in muratura. Inoltre, è fonte di confusione dal punto di vista degli sviluppatori. Perché dovresti ricordare che, nonostante l'utilizzo di display: grid, alcune cose non funzionano a causa dell'utilizzo della muratura?

Una proposta alternativa

Come già accennato, il team di Chrome vorrebbe definire la disposizione a mattoni al di fuori della specifica della griglia. Ciò non significa che sarà limitato a un metodo di layout molto semplice con dimensioni delle colonne identiche. Tutte le demo nel post su WebKit saranno comunque possibili.

Layout con disposizione classica

Quando la maggior parte delle persone pensa alla disposizione a riquadri, immagina un layout con più colonne di dimensioni uguali. Questo viene definito utilizzando il seguente CSS, che richiede un codice meno riga rispetto alla versione con la griglia inclusa equivalente.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 1rem;
}

Piste di dimensioni uguali.

Utilizzare le dimensioni della traccia del tipo di griglia per larghezze di colonna diverse

A parte il problema sopra menzionato relativo alle dimensioni dei canali intrinseci e fissi, puoi utilizzare tutte le dimensioni dei canali che ami dalla griglia. Ad esempio, l'esempio del post del blog WebKit, un pattern di colonne strette e larghe ripetute.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr);
  gap: 1rem;
}

Un motivo di tracce di dimensioni ampie e strette.

Dimensioni aggiuntive dei canali per la disposizione a riquadri

Esistono opzioni di dimensionamento delle tracce aggiuntive che non sono consentite nella griglia perché la griglia è un metodo di layout bidimensionale. Questi formati sarebbero utili in una disposizione a riquadri, ma potrebbero creare confusione se non funzionassero in una griglia.

Piste di dimensioni max-content con riempimento automatico.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, max-content);
  gap: 1rem;
}

Riempimento automatico di tracce di dimensioni auto, che creerà tracce delle stesse dimensioni, di dimensioni automatiche per adattarsi a quella più grande.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
  gap: 1rem;
}

Muratura con canali con dimensioni automatiche.

Consenti ai contenuti di estendersi su più colonne e posiziona gli elementi nel layout a mattonella

Non c'è motivo di non avere contenuti che si estendono su più colonne in una specifica distinta per la disposizione a riquadri. Potrebbe essere utilizzata una proprietà masonry-track, che è un'abbreviazione di masonry-track-start e masonry-track-end, poiché hai una sola dimensione per suddividere gli elementi in un layout a riquadri.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
}

.span-2 {
  masonry-track: span 2; /* spans two columns */
}

.placed {
  masonry-track: 2 / 5; /* covers tracks 2, 3, and 4 */
}

Muratura con elementi posizionati e che si estendono.

Strutture sottostanti o sottostruttura che adottano canali in muratura

Questa funzionalità potrebbe essere supportata con una specifica di muratura separata, sempre con la condizione che i canali misti di dimensioni intrinseche e fisse non siano consentiti. Sarà necessario definire esattamente come deve essere. Non vediamo alcun motivo per cui non dovrebbe funzionare.

Conclusione

Ci piacerebbe arrivare a una specifica che possa essere distribuita in modo interoperabile. Tuttavia, vogliamo farlo in modo che funzioni bene ora e in futuro e che possa essere utilizzato dagli sviluppatori. L'unico modo per risolvere i problemi di rendimento descritti sarebbe aggravare il secondo problema, ovvero la presenza di parti della griglia illegali nella muratura. Non riteniamo che sia una buona soluzione, soprattutto perché è possibile avere tutte le funzionalità della griglia che ti servono mantenendo ben separate le cose diverse.

Se hai un feedback, partecipa alla discussione nel Issue 9041.

Grazie a Bramus, Tab Atkins-Bittner, Una Kravets, Ian Kilpatrick e Chris Harrelson per aver esaminato questo post e le discussioni che lo hanno ispirato.