Flexbox
Um layout de alvenaria dinâmico não é possível com o flexbox, pelo menos não de maneira limpa e eficiente.
Flexbox é um sistema de layout unidimensional. Isso significa que ele pode alinhar itens ao longo de linhas horizontais OU verticais. Um item flexível está confinado à sua linha ou coluna.
Um sistema de grade real é bidimensional, o que significa que ele pode alinhar itens ao longo de linhas horizontais e verticais. Os itens de conteúdo podem se estender por linhas e colunas simultaneamente, o que os itens flexíveis não podem.
É por isso que o flexbox tem uma capacidade limitada para construir grades. É também uma razão pela qual o W3C desenvolveu outra tecnologia CSS3, o Grid Layout .
row wrap
Em um contêiner flexível com flex-flow: row wrap
, os itens flexíveis devem quebrar em novas linhas .
Isso significa que um item flexível não pode quebrar em outro item na mesma linha .
Observe acima como a div nº 3 se divide abaixo da div nº 1 , criando uma nova linha. Não pode quebrar abaixo da div # 2 .
Como resultado, quando os itens não são os mais altos da linha, o espaço em branco permanece, criando lacunas desagradáveis.
column wrap
Se você alternar para flex-flow: column wrap
, um layout semelhante à grade é mais viável. No entanto, um contêiner na direção da coluna tem quatro problemas em potencial imediatamente:
- Os itens flexíveis fluem verticalmente, não horizontalmente (como você precisa neste caso).
- O contêiner se expande horizontalmente, não verticalmente (como o layout do Pinterest).
- Requer que o contêiner tenha uma altura fixa, para que os itens saibam onde embrulhar.
- No momento da redação deste documento, ele possui uma deficiência em todos os principais navegadores, onde o contêiner não se expande para acomodar colunas adicionais .
Como resultado, um contêiner na direção da coluna não é uma opção nesse caso e em muitos outros casos.
Grade CSS com dimensões de item indefinidas
O layout da grade seria uma solução perfeita para o seu problema se as várias alturas dos itens de conteúdo pudessem ser pré-determinadas . Todos os outros requisitos estão dentro da capacidade da Grid.
A largura e a altura dos itens da grade devem ser conhecidas para fechar as lacunas nos itens ao redor.
Portanto, o Grid, que é o melhor CSS para oferecer para a construção de um layout de alvenaria com fluxo horizontal, fica aquém neste caso.
De fato, até que uma tecnologia CSS chegue com a capacidade de fechar automaticamente as lacunas, o CSS em geral não tem solução. Algo assim provavelmente exigiria refletir o documento, então não tenho certeza de quão útil ou eficiente seria.
Você precisará de um script.
As soluções JavaScript tendem a usar posicionamento absoluto, o que remove os itens de conteúdo do fluxo de documentos para reorganizá-los sem falhas. Aqui estão dois exemplos:
Grade CSS com dimensões de item definidas
Para layouts em que a largura e a altura dos itens de conteúdo são conhecidas, aqui está um layout de alvenaria que flui horizontalmente em CSS puro:
grid-container {
display: grid; /* 1 */
grid-auto-rows: 50px; /* 2 */
grid-gap: 10px; /* 3 */
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr)); /* 4 */
}
[short] {
grid-row: span 1; /* 5 */
background-color: green;
}
[tall] {
grid-row: span 2;
background-color: crimson;
}
[taller] {
grid-row: span 3;
background-color: blue;
}
[tallest] {
grid-row: span 4;
background-color: gray;
}
grid-item {
display: flex;
align-items: center;
justify-content: center;
font-size: 1.3em;
font-weight: bold;
color: white;
}
<grid-container>
<grid-item short>01</grid-item>
<grid-item short>02</grid-item>
<grid-item tall>03</grid-item>
<grid-item tall>04</grid-item>
<grid-item short>05</grid-item>
<grid-item taller>06</grid-item>
<grid-item short>07</grid-item>
<grid-item tallest>08</grid-item>
<grid-item tall>09</grid-item>
<grid-item short>10</grid-item>
<grid-item tallest>etc.</grid-item>
<grid-item tall></grid-item>
<grid-item taller></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
<grid-item taller></grid-item>
<grid-item short></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item tallest></grid-item>
<grid-item taller></grid-item>
<grid-item short></grid-item>
<grid-item tallest></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
</grid-container>
Como funciona
- Estabeleça um contêiner de grade em nível de bloco. (
inline-grid
seria a outra opção)
- A
grid-auto-rows
propriedade define a altura das linhas geradas automaticamente. Nesta grade, cada linha tem 50 px de altura.
- A
grid-gap
propriedade é uma abreviação para grid-column-gap
e grid-row-gap
. Esta regra define um intervalo de 10 px entre os itens da grade. (Não se aplica à área entre itens e o contêiner.)
A grid-template-columns
propriedade define a largura das colunas definidas explicitamente.
A repeat
notação define um padrão de colunas (ou linhas) repetidas.
A auto-fill
função diz à grade para alinhar o maior número possível de colunas (ou linhas) sem sobrecarregar o contêiner. (Isso pode criar um comportamento semelhante ao flexflex-wrap: wrap
.)
A minmax()
função define um intervalo de tamanho mínimo e máximo para cada coluna (ou linha). No código acima, a largura de cada coluna será no mínimo 30% do contêiner e no máximo de qualquer espaço livre disponível.
A fr
unidade representa uma fração do espaço livre no contêiner da grade. É comparável à flex-grow
propriedade do flexbox .
Com grid-row
e span
estamos dizendo aos itens da grade quantas linhas eles devem se estender.
Suporte do navegador para CSS Grid
- Chrome - suporte completo a partir de 8 de março de 2017 (versão 57)
- Firefox - suporte completo a partir de 6 de março de 2017 (versão 52)
- Safari - suporte completo a partir de 26 de março de 2017 (versão 10.1)
- Edge - suporte completo a partir de 16 de outubro de 2017 (versão 16)
- IE11 - sem suporte para especificações atuais; suporta versão obsoleta
Aqui está a imagem completa: http://caniuse.com/#search=grid
Recurso de sobreposição de grade legal no Firefox
Nas ferramentas de desenvolvimento do Firefox, quando você inspeciona o contêiner de grade, há um pequeno ícone de grade na declaração CSS. Ao clicar, exibe um esboço da sua grade na página.
Mais detalhes aqui: https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_grid_layouts