O que display: flex faz
Coloque display: flex em um pai e os filhos diretos se alinham em linha, lado a lado, e se esticam até a mesma altura. Essa única declaração substitui floats, inline-block e a maioria dos truques de posicionamento para organizar uma fileira de coisas.
Na primeira caixa, cada div ocupa uma linha inteira. Na segunda, os três itens ficam em uma linha, cada um só com a largura do conteúdo, e One e Three se esticam até a altura de Two. Só o pai mudou: display: flex vai no contêiner, nunca nos itens.
Playground de flexbox
Escolha valores e veja os itens se moverem. A linha de código embaixo da caixa é o CSS do que você está vendo, e a lista embaixo dela é onde o navegador de fato colocou cada item, medido com getBoundingClientRect().
Coisas para testar:
justify-content: space-between: o item 1 fica em x 0 e o item 3 encosta na borda oposta.align-items: center: os três itens mantêm as próprias alturas e os centros se alinham. Com o padrãostretch, o item 1 não tem altura própria e ocupa os 170px inteiros do contêiner.flex-direction: column: agorajustify-contentmove os itens na vertical ealign-itemsna horizontal. As duas propriedades seguem os eixos, não a tela.
Eixo principal e eixo cruzado
Todo contêiner flex tem dois eixos. O eixo principal é a direção em que os itens correm, definida por flex-direction. O eixo cruzado o atravessa.
flex-direction | Eixo principal | Eixo cruzado | justify-content move os itens | align-items move os itens |
|---|---|---|---|---|
row (padrão) | horizontal, na ordem de leitura | vertical | na horizontal | na vertical |
row-reverse | horizontal, invertido | vertical | na horizontal | na vertical |
column | vertical, de cima para baixo | horizontal | na vertical | na horizontal |
column-reverse | vertical, de baixo para cima | horizontal | na vertical | na horizontal |
Em uma página da direita para a esquerda (dir="rtl"), row começa na borda direita, porque o eixo principal segue a direção da escrita.
Propriedades do contêiner
Estas vão no elemento com display: flex:
| Propriedade | O que faz | Padrão |
|---|---|---|
flex-direction | Linha ou coluna, e em qual sentido | row |
flex-wrap | Se os itens passam para uma nova linha quando falta espaço | nowrap |
flex-flow | Shorthand de flex-direction e flex-wrap | row nowrap |
justify-content | Posição e espaçamento ao longo do eixo principal | normal (age como flex-start) |
align-items | Posição dos itens ao longo do eixo cruzado | normal (age como stretch) |
align-content | Espaçamento entre as linhas quando os itens quebram | normal |
gap | Espaço entre os itens (row-gap, column-gap) | 0 |
justify-content e align-items têm uma página própria com todos os valores: justify-content e align-items. Quebra de linha e direção estão na página do flex-wrap.
Propriedades dos itens: flex-grow, flex-shrink, flex-basis
Estas vão nos filhos e decidem como eles dividem a largura do contêiner:
flex-basis: o tamanho de onde o item parte antes de o espaço livre ser dividido (autosignifica "use minha largura ou meu conteúdo").flex-grow: quantas partes do espaço que sobra o item pega.0significa que ele nunca cresce.flex-shrink: quanto o item cede quando não há espaço suficiente.0significa que ele nunca encolhe.
O shorthand flex define os três:
| Você escreve | Que significa | Comportamento |
|---|---|---|
flex: initial (padrão) | 0 1 auto | Tamanho do conteúdo, pode encolher, nunca cresce |
flex: 1 | 1 1 0% | Parte do zero e pega uma parte igual do espaço |
flex: auto | 1 1 auto | Tamanho do conteúdo mais uma parte do espaço que sobra |
flex: none | 0 0 auto | Exatamente o conteúdo ou a largura, nunca cresce nem encolhe |
flex: 2 | 2 1 0% | O dobro da parte de um item com flex: 1 |
Cada linha tem 480px de largura dentro do padding, e os dois gaps de 8px deixam 464px para os itens. As larguras impressas mostram como o espaço foi dividido: cerca de 155px cada na primeira linha, 116 + 232 + 116 na segunda (o item flex: 2 fica com o dobro da parte de cada vizinho) e 100 + 372 na terceira, em que o item flex: none mantém a largura e o outro pega todo o resto.
Layouts reais com flexbox
Um cabeçalho com o logo no início e os links no fim é o layout flex mais comum. margin-inline-start: auto em um item consome todo o espaço livre antes dele e empurra ele e tudo o que vem depois para o fim:
align-items: center alinha o texto maior do logo com os links, e gap espaça os links sem margens para desfazer no último.
Um segundo padrão do dia a dia é a linha de mídia: um ícone de tamanho fixo e um texto que ocupa o resto e quebra linha dentro da própria coluna.
O flex: none é a garantia. Itens flex encolhem por padrão, então se você tirar isso do círculo e também tirar o flex: 1 do texto, o parágrafo espreme o círculo até uns 23px de largura: um oval. Para centralizar uma coisa em uma caixa, o flexbox resolve em duas linhas (justify-content: center; align-items: center); a página de como centralizar uma div compara isso com as outras formas.
order e acessibilidade
A propriedade order e as direções -reverse mudam onde os itens aparecem, não onde estão no HTML. Os leitores de tela e a tecla Tab continuam seguindo a ordem do HTML, então quem usa teclado pode pular do primeiro link na tela para o último. Use isso só para decoração; quando a ordem tem significado, mude o HTML.
Flexbox ou grid
O flexbox trabalha em uma direção de cada vez: os itens de uma linha se dimensionam pelo conteúdo, e uma segunda linha (com quebra) não se alinha com a primeira. O grid trabalha em duas: você define colunas e linhas e os itens se encaixam nelas. Uma barra de navegação, uma barra de ferramentas ou uma linha de formulário é flexbox; uma galeria ou uma página com barra lateral é grid.
Erros comuns
display: flexno item em vez do pai. O contêiner recebedisplay: flex; os filhos dele são os itens.- Esperar que
align-itemsmova os itens na vertical sem altura. Se o contêiner só tem a altura do item mais alto, não há espaço para mover. Dê uma altura ao contêiner; senão, ele está funcionando e só não tem nada a fazer. - Texto que transborda em vez de encolher. Itens flex têm
min-width: auto. Acrescentemin-width: 0ao item que deve encolher. - Usar
flex: 1e estranhar que as larguras sejam diferentes. Itens comflex: 1dividem o espaço por igual, mas um item cujo conteúdo não cabe (uma URL longa, uma imagem) não encolhe abaixo dele.min-width: 0resolve isso também. - Margens entre os itens. Use
gapno contêiner; ele só fica entre os itens. - Aninhar flex sem necessidade. Só os filhos diretos são itens flex. Os netos seguem o layout normal, a menos que o próprio pai deles também tenha
display: flex.
Perguntas frequentes
O que display: flex faz?
Transforma um elemento em um contêiner flex. Os filhos diretos viram itens flex e são dispostos em linha por padrão, lado a lado, esticados até a mesma altura, com propriedades como justify-content, align-items e gap controlando como dividem o espaço.
O que significa flex: 1?
flex: 1 é a forma curta de flex: 1 1 0%: o item pode crescer (flex-grow: 1), pode encolher (flex-shrink: 1) e parte de um tamanho zero (flex-basis: 0%). Itens que têm todos flex: 1 dividem o espaço livre por igual, então terminam com a mesma largura, a menos que o conteúdo não caiba.
Qual a diferença entre justify-content e align-items?
justify-content posiciona os itens ao longo do eixo principal (na horizontal em uma linha), e align-items ao longo do eixo cruzado (na vertical em uma linha). Com flex-direction: column os dois eixos se invertem, então justify-content passa a ser vertical.
Devo usar flexbox ou grid?
Use flexbox para uma única linha ou coluna cujos itens se dimensionam pelo conteúdo: barras de navegação, grupos de botões, um rótulo ao lado de um input. Use grid quando quiser linhas e colunas que se alinham entre si, como uma grade de cards ou um layout de página.
Por que meu item flex transborda o contêiner?
Um item flex tem min-width: auto por padrão, então se recusa a encolher abaixo da largura da palavra mais longa ou do filho mais largo. Defina min-width: 0 (ou overflow: hidden) no item para deixá-lo encolher, por exemplo para o text-overflow: ellipsis funcionar.
O flexbox funciona em elementos inline como span?
Sim. Qualquer elemento com display: flex é um contêiner flex, e os filhos viram itens flex seja qual for o display deles, então filhos <span> deixam de ser inline e aceitam largura, altura e margin como blocos.