flex-wrap: uma linha, ou quantas forem necessárias
Por padrão, um contêiner flex mantém todos os itens em uma linha (flex-wrap: nowrap) e os encolhe para caber. flex-wrap: wrap deixa os itens manterem o tamanho e passarem para a linha seguinte:
Cada item pede 100px, cinco deles em uma caixa de 340px. Cinco itens e quatro gaps de 8px precisam de 532px, então sem quebra cada item é espremido para uns 62px, porque itens flex encolhem por padrão. Com wrap eles ficam com 100px: três cabem na primeira linha e os outros dois vão para uma segunda linha.
Valores de flex-wrap
| Valor | O que acontece |
|---|---|
nowrap (padrão) | Uma linha. Os itens encolhem e transbordam o contêiner quando não conseguem mais encolher |
wrap | Os itens que não cabem começam uma nova linha embaixo |
wrap-reverse | Igual, mas as novas linhas se empilham para cima: a primeira linha fica embaixo |
Veja os itens quebrarem
Arraste o controle deslizante para mudar a largura do contêiner. O painel conta as linhas e diz quantos itens há em cada uma:
Com 400px, quatro itens de 90px e três gaps de 8px (384px) cabem em uma linha, então fica 4 + 2. Arraste para perto de 620px e os seis cabem em uma linha; arraste para perto de 120px e cada item fica com uma linha só para ele.
flex-direction: linha ou coluna
flex-direction define a direção em que os itens correm, que é o eixo principal:
| Valor | Os itens correm | Primeiro item |
|---|---|---|
row (padrão) | lado a lado, na direção da escrita | no início da linha |
row-reverse | lado a lado, invertidos | no fim da linha |
column | empilhados, de cima para baixo | no topo |
column-reverse | empilhados, de baixo para cima | na base |
Nas duas caixas row, os itens se esticam até a altura toda da caixa, porque align-items: stretch age através da linha. Nas caixas column, eles se esticam até a largura toda, pelo mesmo motivo. Os eixos giraram, e todas as propriedades de alinhamento giraram junto (a página do justify-content mostra isso em detalhe).
flex-flow: os dois em uma linha
flex-flow é o shorthand de flex-direction seguido de flex-wrap:
.cards { flex-flow: row wrap; } /* flex-direction: row; flex-wrap: wrap; */
.stack { flex-flow: column nowrap; } /* flex-direction: column; flex-wrap: nowrap; */
Cards responsivos com wrap e sem media query
Dê a cada item um tamanho inicial com flex: 1 1 180px e deixe a linha quebrar. Cada item cresce para preencher a linha, e quando uma linha não comporta outro item de 180px, o próximo quebra:
Em uma prévia com cerca de 800px de largura, três cards cabem na primeira linha (uns 253px cada) e os dois últimos dividem a segunda linha, em que cada um cresce para uns 386px. É assim que o flexbox funciona: cada linha divide o próprio espaço, então os cards de uma última linha curta ficam mais largos que os de cima. Se você quer que o último card tenha a mesma largura dos outros, use grid com repeat(auto-fill, minmax(180px, 1fr)) (veja a página do grid).
align-content: espaçar as linhas
Quando um contêiner quebra linhas e é mais alto que elas, align-content decide onde as linhas ficam. Ele aceita os mesmos valores do justify-content, mais stretch:
Na primeira caixa, as duas linhas ficam no topo. Na segunda, a primeira linha fica no topo e a segunda na base, com toda a altura que sobra entre elas.
Ordem invertida e acessibilidade
row-reverse, column-reverse e wrap-reverse só mudam onde os itens são desenhados. Os leitores de tela e a tecla Tab continuam seguindo a ordem do HTML, então quem usa teclado percorre os itens no sentido oposto ao que vê. Inverta só por efeito visual; quando a ordem carrega significado, mude-a no HTML.
Erros comuns
- Itens que encolhem em vez de quebrar. Itens com
flex: 1partem de umflex-basis0 e se espremem em uma linha. Dê a eles uma base de verdade, comoflex: 1 1 200px. - Colocar o
flex-wrapnos itens. Ele pertence ao contêiner flex. - Usar
align-itemspara espaçar linhas quebradas. Ele alinha os itens dentro de cada linha; as próprias linhas se movem comalign-content. - Um último item sozinho esticado na linha inteira. Isso é o
flex-growem uma linha com um só item. Use grid se todos os cards precisarem ter a mesma largura. - Esperar que
flex-direction: columnpreencha uma altura. Um contêiner em coluna só tem a altura do conteúdo, a menos que você dê umheighta ele, então ojustify-contentnão tem espaço para agir.
Perguntas frequentes
O que flex-wrap: wrap faz?
Deixa os itens flex passarem para uma nova linha quando não cabem em uma. Com o nowrap padrão, os itens ficam em uma linha e encolhem, ou transbordam o contêiner se não conseguirem encolher mais.
Por que o flex-wrap não funciona?
A quebra só acontece quando os tamanhos iniciais dos itens somam mais que o contêiner. Itens com flex: 1 partem de um flex-basis 0, então nunca quebram; dê a eles um tamanho inicial de verdade (flex: 1 1 200px ou width: 200px). Confira também se o flex-wrap está no contêiner flex, e não nos itens.
Qual a diferença entre flex-direction row e column?
row (o padrão) põe os itens lado a lado na direção da escrita, e column os empilha de cima para baixo. O eixo principal gira junto, então em uma coluna o justify-content age na vertical e o align-items na horizontal.
O que é flex-flow?
Um shorthand de flex-direction e flex-wrap em uma declaração: flex-flow: row wrap; é o mesmo que flex-direction: row; flex-wrap: wrap;.
Qual a diferença entre align-items e align-content?
align-items posiciona os itens dentro da linha deles. align-content posiciona as próprias linhas dentro do contêiner, então só importa quando o contêiner tem flex-wrap: wrap e é mais alto que as linhas.