Una proposta alternativa per la muratura CSS

Il team di Chrome vuole vedere l'implementazione sul web di layout di tipo muratura. Tuttavia, riteniamo che implementarla come parte della specifica della griglia CSS, come proposto nel recente post di WebKit, sarebbe un errore. Riteniamo anche che il post WebKit contestasse una versione di muratura che nessuno avrebbe proposto.

Pertanto, questo post ha lo scopo di spiegare perché noi di Chrome abbiamo dubbi riguardo all'implementazione di elementi in muratura come parte della specifica del layout di griglia CSS e chiarire cosa consente esattamente la proposta alternativa. In breve:

  • Il team di Chrome vuole sbloccare i lavori in muratura, sappiamo che è qualcosa che gli sviluppatori vogliono.
  • L'aggiunta di muratura alla specifica della griglia è problematica per altri motivi diversi dal fatto che si pensi che la muratura sia una griglia o meno.
  • La definizione della muratura al di fuori della specifica della griglia non impedisce la presenza di più dimensioni delle tracce per la muratura, né l'utilizzo di proprietà come allineamento o intervalli o qualsiasi altra caratteristica utilizzata nel layout della griglia.

La muratura dovrebbe essere parte della griglia?

Il team di Chrome ritiene che la muratura debba essere un metodo di layout separato, definito utilizzando display: masonry (o un'altra parola chiave dovrebbe essere scelto un nome migliore). Più avanti in questo post, puoi vedere alcuni esempi di come potrebbe apparire nel codice.

Ci sono due motivi correlati per cui riteniamo che la muratura sia definita meglio al di fuori del layout a griglia: il potenziale problema di prestazioni del layout e il fatto che sia la muratura sia la griglia hanno caratteristiche che hanno senso in un metodo di layout e non nell'altro.

Rendimento

Griglia e muratura sono opposte per quanto riguarda le dimensioni e il posizionamento del browser. Quando si crea una griglia, tutti gli elementi vengono posizionati prima del layout e il browser sa esattamente cosa c'è in ogni traccia. Ciò consente il complesso dimensionamento intrinseco, così utile nella griglia. Con i lavori di muratura, gli elementi vengono posizionati così come sono disposti e il browser non sa quanti ne sono in ogni traccia. Non si tratta di un problema con tutte le tracce di dimensioni intrinseche o con tutte le tracce di dimensioni fisse, bensì con il mix di tracce fisse e intrinseche. Per risolvere il problema, il browser deve eseguire una fase di pre-layout del layout di ogni elemento in tutti i modi possibili per ottenere le misurazioni, con una griglia di grandi dimensioni che ciò potrebbe contribuire a problemi di prestazioni del layout.

Di conseguenza, se avevi un layout in muratura con una definizione di traccia pari a grid-template-columns: 200px auto 200px, una procedura molto comune nella griglia, riscontrerai qualche problema. Questi problemi diventano esponenziali con l'aggiunta di sottogriglie.

Esiste un argomento secondo cui la maggior parte delle persone non si imbatterà in questo scenario, tuttavia sappiamo già che le persone hanno reti molto grandi. Non vogliamo spedire qualcosa che abbia dei limiti al modo in cui può essere usato, quando c'è un approccio alternativo.

Cosa facciamo riguardo agli aspetti non utili di ogni metodo di layout?

Quando flexbox e griglia sono diventati parte del CSS, gli sviluppatori spesso si sono accorti di comportarsi in modo incoerente. L'incoerenza è dovuta a ipotesi su come funzionava il layout basato su un layout a blocchi. Nel corso del tempo, gli sviluppatori hanno iniziato a capire i contesti di formattazione. Quando passiamo a un contesto di formattazione griglia o flessibile, alcuni elementi si comportano in modo diverso. Ad esempio, quando sei in Flexbox, non sono disponibili tutti i metodi di allineamento, poiché flexbox è unidimensionale.

L'inserimento di elementi in muratura nella griglia interrompe questo chiaro collegamento tra il contesto della formattazione e la disponibilità di elementi come le proprietà di allineamento, che sono definiti nella specifica dell'allineamento dei riquadri in base al contesto di formattazione.

Se decidiamo di risolvere il problema di prestazioni descritto in precedenza rendendo illegali le definizioni di binario intrinseco e fisso nelle murature, dovrai ricordare che un modello molto comune per i layout a griglia non funziona per la muratura.

Esistono anche pattern che avrebbero senso nell'ambito dei lavori di muratura, ad esempio grid-template-columns: repeat(auto-fill, max-content), perché non hai vincoli incrociati, ma devi rimanere non valido nella griglia. Di seguito è riportato un elenco di proprietà che prevediamo che si comportino in modo diverso o che abbiano valori validi diversi.

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

Ci sarà anche un requisito per specificare cosa succede in tutti i nuovi casi di errore causati dagli sviluppatori che usano un valore non valido in griglia con muratura o senza muratura. Ad esempio, puoi utilizzare grid-template-columns: masonry o grid-template-rows: masonry ma non entrambi contemporaneamente. Cosa succede se si utilizzano entrambi contemporaneamente? Questi dettagli devono essere specificati in modo che tutti i browser facciano la stessa cosa.

Tutto questo diventa complicato dal punto di vista delle specifiche, ora e in futuro. Dovremo fare in modo che tutto tenga conto dei lavori di muratura e se lavori o meno nella muratura. È anche poco chiara dal punto di vista degli sviluppatori. Perché dovresti tenere presente che, nonostante display: grid, alcune cose non funzionano se usi la muratura?

Una proposta alternativa

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

Layout classico in muratura

La maggior parte delle persone pensa alla muratura, pensa a un layout con più colonne di dimensioni uguali. Verrà definito utilizzando il seguente CSS, che richiede un codice senza riga rispetto alla versione in bundle nella griglia equivalente.

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

Tracce di dimensioni uguali.

Utilizza il dimensionamento delle tracce del tipo di griglia per larghezze delle colonne diverse

A parte il già menzionato problema con il dimensionamento intrinseco e fisso delle tracce, puoi utilizzare le dimensioni della traccia che preferisci per la griglia. Ad esempio l'esempio tratto dal post del blog di WebKit, un modello di ripetizione di colonne strette e più larghe.

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

Uno schema di tracce larghe e strette.

Ulteriori dimensioni dei binari per muratura

Esistono altre opzioni per le dimensioni delle tracce che non sono consentite nella griglia poiché questo è un metodo di layout bidimensionale. Queste sono utili nella muratura, ma confonderebbero se non funzionassero nella griglia.

Compilazione automatica delle tracce delle dimensioni di max-content.

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

Le tracce delle dimensioni auto con compilazione automatica, in modo da creare tracce delle stesse dimensioni, ridimensionate automaticamente per adattarsi a quella più grande.

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

Lavori in muratura con guide di dimensioni automatiche.

Consenti ai contenuti di estendere le colonne e posizionare gli elementi nel layout in muratura

Non c'è motivo di non avere contenuti che si estendono su colonne in una specifica della muratura separata. Potrebbe essere utilizzata una proprietà masonry-track, un'abbreviazione di masonry-track-start e masonry-track-end, in quanto è possibile definire una sola dimensione per coprire gli elementi in un layout in muratura.

.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 */
}

Lavori in muratura con elementi posizionati e sparsi.

Sottomassoneria o sottorete che adotta canali per muratura

Ciò potrebbe essere supportato con specifiche di muratura separate, sempre con la condizione che non siano consentite tracce intrinseche e fisse. Dovrà essere definito esattamente come appare. Non vediamo un motivo per cui non funziona.

Conclusione

Vorremmo arrivare a una specifica che può essere spedibile in modo intero. Tuttavia, vogliamo farlo in un modo che funzioni bene ora e in futuro e su cui gli sviluppatori si possano fare affidamento. L'unico modo per affrontare i problemi di prestazioni descritti è quello di rendere peggiore il secondo problema, quello della presenza di parti della griglia illegali in muratura. Non riteniamo che sia una buona soluzione, soprattutto quando è possibile avere tutte le funzionalità della griglia che si desidera mantenendo chiaramente separati gli elementi che sono diversi.

Se hai feedback, partecipa alla discussione nel Issue 9041.

Grazie a Bramus, Tab Atkins-Bittner, Una Kravets, Ian Kilpatrick e Chris Harrelson per la revisione di questo post e le discussioni alla base.