Menu

flex-wrap e flex-direction no CSS: linhas, colunas, quebra

flex-wrap decide se os itens flex se espremem em uma linha ou passam para a próxima, e flex-direction decide se eles correm em linha ou em coluna. Veja os dois com exemplos ao vivo, o shorthand flex-flow, align-content e uma fileira de cards responsiva sem media queries.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

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

ValorO que acontece
nowrap (padrão)Uma linha. Os itens encolhem e transbordam o contêiner quando não conseguem mais encolher
wrapOs itens que não cabem começam uma nova linha embaixo
wrap-reverseIgual, 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:

ValorOs itens corremPrimeiro item
row (padrão)lado a lado, na direção da escritano início da linha
row-reverselado a lado, invertidosno fim da linha
columnempilhados, de cima para baixono topo
column-reverseempilhados, de baixo para cimana 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: 1 partem de um flex-basis 0 e se espremem em uma linha. Dê a eles uma base de verdade, como flex: 1 1 200px.
  • Colocar o flex-wrap nos itens. Ele pertence ao contêiner flex.
  • Usar align-items para espaçar linhas quebradas. Ele alinha os itens dentro de cada linha; as próprias linhas se movem com align-content.
  • Um último item sozinho esticado na linha inteira. Isso é o flex-grow em uma linha com um só item. Use grid se todos os cards precisarem ter a mesma largura.
  • Esperar que flex-direction: column preencha uma altura. Um contêiner em coluna só tem a altura do conteúdo, a menos que você dê um height a ele, então o justify-content nã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.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR