Estou trabalhando em um layout aninhado de flexbox que deve funcionar da seguinte maneira:
O nível mais externo ( ul#main
) é uma lista horizontal que deve ser expandida para a direita quando mais itens forem adicionados a ela. Se crescer muito, deve haver uma barra de rolagem horizontal.
#main {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
overflow-x: auto;
/* ...and more... */
}
Cada item desta lista ( ul#main > li
) possui um cabeçalho ( ul#main > li > h2
) e uma lista interna ( ul#main > li > ul.tasks
). Essa lista interna é vertical e deve quebrar em colunas quando necessário. Ao agrupar em mais colunas, sua largura deve aumentar para abrir espaço para mais itens. Esse aumento de largura deve ser aplicado também ao item que contém a lista externa.
.tasks {
flex-direction: column;
flex-wrap: wrap;
/* ...and more... */
}
Meu problema é que as listas internas não quebram quando a altura da janela fica muito pequena. Eu tentei muitas adulterações com todas as propriedades flex, tentando seguir as diretrizes do CSS-Tricks meticulosamente, mas sem sorte.
Este JSFiddle mostra o que tenho até agora.
Resultado esperado (o que eu quero) :
Resultado real (o que eu recebo) :
Resultado mais antigo (o que obtive em 2015) :
ATUALIZAR
Após alguma investigação, isso está começando a parecer um problema maior. Todos os principais navegadores se comportam da mesma maneira e não tem nada a ver com o design do meu flexbox sendo aninhado. Layouts de colunas flexbox ainda mais simples se recusam a aumentar a largura da lista quando os itens são quebrados.
Este outro JSFiddle demonstra claramente o problema. Nas versões atuais do Chrome, Firefox e IE11, todos os itens são agrupados corretamente; a altura da lista aumenta no row
modo, mas sua largura não aumenta no column
modo. Além disso, não há refluxo imediato de elementos ao alterar a altura de um column
modo, mas existe no row
modo.
No entanto, as especificações oficiais (veja especificamente o exemplo 5) parecem indicar que o que eu quero fazer deve ser possível.
Alguém pode apresentar uma solução alternativa para esse problema?
ATUALIZAÇÃO 2
Depois de muitas experiências usando o JavaScript para atualizar a altura e a largura de vários elementos durante eventos de redimensionamento, cheguei à conclusão de que é muito complexo e complicado demais tentar resolvê-lo dessa maneira. Além disso, adicionar JavaScript definitivamente quebra o modelo do flexbox, que deve ser mantido o mais limpo possível.
Por enquanto, estou retornando ao overflow-y: auto
invés de flex-wrap: wrap
para que o contêiner interno role verticalmente quando necessário. Não é bonito, mas é um caminho a seguir que pelo menos não quebra muito a usabilidade.
column wrap
não exiba sua largura ao quebrar. Consulte code.google.com/p/chromium/issues/detail?id=247963 para obter mais informações.Respostas:
O problema
Isso parece uma deficiência fundamental no layout flexível.
Um contêiner flexível na direção da coluna não será expandido para acomodar colunas adicionais. (Este não é um problema no
flex-direction: row
.)Esta pergunta foi feita muitas vezes (veja a lista abaixo), sem respostas limpas em CSS.
É difícil definir isso como um bug, porque o problema ocorre em todos os principais navegadores. Mas levanta a questão:
Você pensaria que pelo menos um deles acertaria. Só posso especular sobre o motivo. Talvez tenha sido uma implementação tecnicamente difícil e tenha sido arquivada para essa iteração.
ATUALIZAÇÃO: o problema parece ter sido resolvido no Edge v16.
Ilustração do Problema
O OP criou uma demonstração útil ilustrando o problema. Estou copiando aqui: http://jsfiddle.net/nwccdwLw/1/
Opções de solução alternativa
Soluções Hacky da comunidade Stack Overflow:
"Parece que esse problema não pode ser resolvido apenas com CSS, então proponho a você uma solução JQuery."
"É curioso que a maioria dos navegadores não tenha implementado corretamente os contêineres flexíveis de coluna, mas o suporte aos modos de gravação é razoavelmente bom. Portanto, você pode usar um contêiner flexível de linha com um modo de gravação vertical".
Mais análise
Relatório de erro do Chromium
Resposta de Mark Amery
Outras postagens descrevendo o mesmo problema
fonte
Chegou atrasado à festa, mas ainda estava enfrentando esse problema ANOS depois. Acabou encontrando uma solução usando a grade. No contêiner, você pode usar
Eu tenho um exemplo no CodePen que alterna entre o problema do flexbox e a correção da grade: https://codepen.io/MandeeD/pen/JVLdLd
fonte
grid-row-end: span X;
se precisar de alguns itens para ocupar mais linhas.É lamentável que tantos navegadores importantes sofram desse bug após muitos anos. Considere uma solução alternativa para Javascript. Sempre que a janela do navegador é redimensionada ou o conteúdo é adicionado ao elemento, execute esse código para redimensionar a largura adequada. Você pode definir uma diretiva em sua estrutura para fazer isso por você.
fonte
Acabei de encontrar uma solução PURE CSS realmente incrível aqui.
https://jsfiddle.net/gcob492x/3/
O mais complicado: defina
writing-mode: vertical-lr
na lista div e depoiswriting-mode: horizontal-tb
no item da lista. Eu tive que ajustar os estilos no JSFiddle (remova muitos estilos de alinhamento, que não são necessários para a solução).Nota: o comentário diz que só funciona em navegadores baseados no Chromium, e não no Firefox. Eu só testei pessoalmente no Chrome. É possível que haja uma maneira de modificar isso para fazê-lo funcionar em outros navegadores ou se houve atualizações nos referidos navegadores que fazem isso funcionar.
Grande mensagem para este comentário: quando os itens do flexbox são agrupados no modo de coluna, o contêiner não aumenta sua largura . A pesquisa nesse tópico levou-me a https://bugs.chromium.org/p/chromium/issues/detail?id=507397#c39, o que me levou a este JSFiddle.
fonte
Como ainda não foi sugerida nenhuma solução ou solução alternativa, consegui obter o comportamento solicitado com uma abordagem um pouco diferente. Em vez de separar o layout em 3 divs diferentes, estou adicionando todos os itens em 1 div e criando a separação com mais divs no meio.
A solução proposta é codificada, assumindo que temos três seções, mas pode ser estendida para uma genérica. A idéia principal é explicar como podemos alcançar esse layout.
:before
em cada primeiro item, podemos localizar o título de cada seção.space
cria a lacuna entre as seçõesspace
não cobrirá toda a altura da seção, também adicionarei:after
às seções, posicionando-a com posição absoluta e fundo branco.z-index: -1
.fonte
Possível solução JS ..
fonte
columns
propriedade style pode ser o ponto de partida para uma solução funcional. Talvez ajustando o número de colunas e a largura da ul.