A equipe do Chrome quer implementar layouts do tipo "muro de tijolos" na Web. No entanto, acreditamos que implementá-lo como parte da especificação do CSS Grid, conforme proposto na postagem recente do WebKit, seria um erro. Também achamos que a postagem do WebKit argumentou contra uma versão de alvenaria que ninguém estava propondo.
Portanto, esta postagem tem como objetivo explicar por que, no Chrome, temos preocupações sobre a implementação de alvenaria como parte da especificação do layout de grade CSS e esclarecer exatamente o que a proposta alternativa permite. Resumindo:
- A equipe do Chrome está muito interessada em desbloquear a disposição em blocos, e sabemos que é algo que os desenvolvedores querem.
- Adicionar a disposição em blocos à especificação da grade é problemático por outros motivos além de você pensar que a disposição em blocos é uma grade ou não.
- Definir a disposição fora da especificação da grade não impede vários tamanhos de faixa para a disposição ou o uso de propriedades como alinhamento ou lacunas ou qualquer outro recurso usado no layout de grade.
A disposição em blocos precisa fazer parte da grade?
A equipe do Chrome acredita que a disposição em blocos precisa ser um método de layout
separado,
definido usando display: masonry
(ou outra palavra-chave, caso um nome melhor seja
decidido). Mais adiante nesta postagem, você vai conferir alguns exemplos de como isso pode
parecer no código.
Há dois motivos relacionados para que achamos que a disposição em mosaico é melhor definida fora do layout de grade: o potencial de problemas de desempenho do layout e o fato de que a disposição em mosaico e a grade têm recursos que fazem sentido em um método de layout, mas não no outro.
Desempenho
Grid e masonry são opostos em termos de como o navegador lida com o tamanho e a posição. Quando uma grade é disposta, todos os itens são colocados antes do layout, e o navegador sabe exatamente o que está em cada faixa. Isso permite o dimensionamento intrínseco complexo que é tão útil na grade. Com a alvenaria, os itens são colocados conforme são organizados, e o navegador não sabe quantos estão em cada faixa. Isso não é um problema com todas as faixas de tamanho intrínseco ou todas as faixas de tamanho fixo, mas é se você misturar faixas fixas e intrínsecas. Para contornar o problema, o navegador precisa fazer uma etapa de pré-layout para posicionar cada item de todas as maneiras possíveis para obter medições. Com uma grade grande, isso contribuiria para problemas de desempenho do layout.
Portanto, se você tivesse um layout de alvenaria com uma definição de faixa de
grid-template-columns: 200px auto 200px
, algo muito comum de se fazer na grade,
você começaria a ter problemas. Esses problemas se tornam exponenciais quando você adiciona
subgrades.
Há um argumento de que a maioria das pessoas não vai encontrar esse problema, mas já sabemos que as pessoas têm grades muito grandes. Não queremos enviar algo que tenha limites de uso quando há uma abordagem alternativa.
O que fazer com as coisas que não fazem sentido em cada método de layout?
Quando o flexbox e a grade se tornaram parte do CSS, os desenvolvedores muitas vezes sentiam que eles se comportavam de maneira inconsistente. A inconsistência que eles estavam enfrentando era devido a suposições mantidas por muito tempo sobre como o layout funcionava, com base no layout de blocos. Com o tempo, os desenvolvedores começaram a entender os contextos de formatação. Quando mudamos para um contexto de formatação flexível ou de grade, algumas coisas se comportam de maneira diferente. Por exemplo, você sabe que, quando está no flexbox, nem todos os métodos de alinhamento estão disponíveis, porque o flexbox é unidimensional.
O agrupamento de blocos na grade quebra essa ligação clara entre o contexto de formatação e a disponibilidade de elementos como propriedades de alinhamento, que são definidas na especificação de alinhamento de caixa por contexto de formatação.
Se decidirmos lidar com o problema de desempenho descrito anteriormente, tornando as definições de faixas mistas intrínsecas e fixas ilegais na disposição em blocos, você vai precisar lembrar que um padrão muito comum para layouts de grade não funciona para disposição em blocos.
Há também padrões que fariam sentido na alvenaria, por exemplo,
grid-template-columns: repeat(auto-fill, max-content)
, porque você não tem
restrições cruzadas, mas precisa permanecer inválido na grade. Confira a seguir uma
lista de propriedades que devem se comportar
de maneira diferente
ou ter valores válidos diferentes.
grid-template-areas
: na disposição em bloco, só é possível especificar a linha inicial na direção que não é de disposição em bloco.grid-template
: a abreviação precisaria considerar todas as diferenças.- Acompanhe os valores de dimensionamento de
grid-template-columns
egrid-template-rows
devido a diferenças nos valores legais. grid-auto-flow
não se aplica a alvenaria, emasonry-auto-flow
não se aplica a grade. A mesclagem cria problemas de elementos inválidos devido ao método de layout em que você está.- O grid tem quatro propriedades de posicionamento (
grid-column-start
e assim por diante), o layout de blocos tem apenas duas. - O Grid pode usar as seis propriedades
justify-*
ealign-*
, mas o Masonry usa apenas um subconjunto, como o flexbox.
Também será necessário especificar o que acontece em todos os novos casos de erro
causados por desenvolvedores que usam um valor inválido em grade com
ou sem disposição em blocos. Por exemplo, é válido usar
grid-template-columns: masonry
ou grid-template-rows: masonry
,
mas não os dois ao mesmo tempo. O que acontece se você usar os dois ao mesmo tempo?
Esses detalhes precisam ser especificados para que todos os navegadores
façam a mesma coisa.
Tudo isso se torna complicado do ponto de vista da especificação, agora e no
futuro. Precisamos garantir que tudo leve em conta a disposição em blocos e
se ela funciona ou não. Também é confuso do ponto
de vista dos desenvolvedores. Por que você precisa se lembrar de que, apesar de
usar display: grid
, algumas coisas não funcionam por causa do uso de disposição em blocos?
Uma proposta alternativa
Como já mencionado, a equipe do Chrome quer definir a disposição em blocos fora da especificação de grade. Isso não significa que ele seria limitado a um método de layout muito simples com tamanhos de coluna idênticos. Todas as demonstrações no post do WebKit ainda seriam possíveis.
Layout de alvenaria clássico
Quando a maioria das pessoas pensa em alinhamento de blocos, imagina um layout com várias colunas de tamanho igual. Isso seria definido usando o CSS a seguir, que precisa de uma linha a menos de código do que a versão do pacote de grade equivalente.
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, minmax(14rem, 1fr));
gap: 1rem;
}
Usar o dimensionamento de faixa do tipo grade para diferentes larguras de coluna
Além do problema mencionado anteriormente com o tamanho misto intrínseco e fixo da faixa, é possível usar todos os tamanhos de faixa que você gosta da grade. Como o exemplo da postagem do blog do WebKit, um padrão de colunas estreitas e largas repetidas.
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr);
gap: 1rem;
}
Tamanho de faixa adicional para o modo de mosaico
Há outras opções de dimensionamento de faixa que não são permitidas na grade, porque ela é um método de layout bidimensional. Elas seriam úteis em muros de pedra, mas seria confuso se não funcionassem em grade.
Preenchimento automático de faixas de tamanho max-content
.
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, max-content);
gap: 1rem;
}
Preenchimento automático de faixas do tamanho auto
, que cria faixas do mesmo tamanho,
com tamanho automático para acomodar a maior.
.masonry {
display: masonry;
masonry-template-tracks: repeat(auto-fill, auto);
gap: 1rem;
}
Permitir que o conteúdo se estenda por colunas e coloque itens no layout de alvenaria
Não há motivo para não ter conteúdo que se estende por colunas em uma especificação
de disposição em blocos separada. Isso pode usar uma propriedade masonry-track
, sendo uma abreviação de
masonry-track-start
e masonry-track-end
, já que você tem apenas uma dimensão para
agrupar as coisas em um layout de alvenaria.
.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 */
}
Submalha ou subgrade adotando faixas de alvenaria
Isso pode ser aceito com uma especificação de alvenaria separada, novamente com a disposição de que faixas de tamanho fixo e intrínseco misturadas não são permitidas. É necessário definir exatamente como isso vai funcionar. Não vemos motivo para isso não funcionar.
Conclusão
Gostaríamos de chegar a uma especificação que possa ser enviada de forma interoperável. No entanto, queremos fazer isso de uma maneira que funcione bem agora e no futuro e que possa ser confiável pelos desenvolvedores. A única maneira de lidar com os problemas de desempenho descritos seria piorar o segundo problema, de ter partes da grade ilegais na disposição em blocos. Não achamos que essa seja uma boa solução, especialmente quando é possível ter todos os recursos de grade que você quer e manter as coisas diferentes claramente separadas.
Se você tiver algum feedback, participe da discussão em Issue 9041.
Agradecemos a Bramus, Tab Atkins-Bittner, Una Kravets, Ian Kilpatrick e Chris Harrelson pela revisão desta postagem e das discussões que a fundamentaram.