Menu

Flexbox CSS: display flex, eixos, alinhamento e flex

O flexbox organiza itens em uma linha ou coluna e controla como eles dividem o espaço e se alinham. Veja display: flex, o eixo principal e o eixo cruzado, todas as propriedades do contêiner, flex-grow, flex-shrink e flex-basis, com um playground ao vivo que mede onde cada item fica.

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

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ão stretch, o item 1 não tem altura própria e ocupa os 170px inteiros do contêiner.
  • flex-direction: column: agora justify-content move os itens na vertical e align-items na 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-directionEixo principalEixo cruzadojustify-content move os itensalign-items move os itens
row (padrão)horizontal, na ordem de leituraverticalna horizontalna vertical
row-reversehorizontal, invertidoverticalna horizontalna vertical
columnvertical, de cima para baixohorizontalna verticalna horizontal
column-reversevertical, de baixo para cimahorizontalna verticalna 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:

PropriedadeO que fazPadrão
flex-directionLinha ou coluna, e em qual sentidorow
flex-wrapSe os itens passam para uma nova linha quando falta espaçonowrap
flex-flowShorthand de flex-direction e flex-wraprow nowrap
justify-contentPosição e espaçamento ao longo do eixo principalnormal (age como flex-start)
align-itemsPosição dos itens ao longo do eixo cruzadonormal (age como stretch)
align-contentEspaçamento entre as linhas quando os itens quebramnormal
gapEspaç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 (auto significa "use minha largura ou meu conteúdo").
  • flex-grow: quantas partes do espaço que sobra o item pega. 0 significa que ele nunca cresce.
  • flex-shrink: quanto o item cede quando não há espaço suficiente. 0 significa que ele nunca encolhe.

O shorthand flex define os três:

Você escreveQue significaComportamento
flex: initial (padrão)0 1 autoTamanho do conteúdo, pode encolher, nunca cresce
flex: 11 1 0%Parte do zero e pega uma parte igual do espaço
flex: auto1 1 autoTamanho do conteúdo mais uma parte do espaço que sobra
flex: none0 0 autoExatamente o conteúdo ou a largura, nunca cresce nem encolhe
flex: 22 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: flex no item em vez do pai. O contêiner recebe display: flex; os filhos dele são os itens.
  • Esperar que align-items mova 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. Acrescente min-width: 0 ao item que deve encolher.
  • Usar flex: 1 e estranhar que as larguras sejam diferentes. Itens com flex: 1 dividem 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: 0 resolve isso também.
  • Margens entre os itens. Use gap no 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.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR