O Flexbox chegou a todos os principais navegadores por volta de 2015 e imediatamente resolveu o problema que os desenvolvedores vinham contornando há uma década: o alinhamento vertical. Mas a maioria das pessoas aprendeu ao contrário — memorizou justify-content: center de uma folha de referência sem entender por que funciona. Quando o layout não se comporta como esperado, essa lacuna de compreensão transforma uma tarefa de cinco minutos em uma hora de tentativa e erro. Este guia constrói o modelo mental primeiro, depois cobre todas as propriedades que realmente importam em projetos reais.

O Modelo Mental: Um Eixo por Vez

O conceito central do Flexbox é que ele dispõe itens ao longo de um único eixo. Há um eixo principal — a direção em que os itens fluem — e um eixo transversal, que corre perpendicularmente. O insight crítico que quase todo iniciante perde: flex-direction determina qual eixo é qual. Todo o resto decorre disso.

css
/* Default: main axis runs LEFT → RIGHT, cross axis runs TOP → BOTTOM */
.container {
  display: flex;
  flex-direction: row; /* default */
}

/* Rotated: main axis now runs TOP → BOTTOM, cross axis runs LEFT → RIGHT */
.container {
  display: flex;
  flex-direction: column;
}

/*
  justify-content  →  controls alignment on the MAIN axis
  align-items      →  controls alignment on the CROSS axis

  This is why centering something in both axes looks like this:
*/
.center-both {
  display: flex;
  justify-content: center; /* horizontally centred (main axis = row) */
  align-items: center;     /* vertically centred (cross axis)        */
}
A confusão que pega todo mundo: quando você muda para flex-direction: column, justify-content não controla mais o alinhamento horizontal — controla o alinhamento vertical, porque o eixo principal girou. align-items agora controla o horizontal. Tenha essa rotação em mente sempre que algo não estiver alinhando onde você espera.

Propriedades do Contêiner

Essas propriedades vão no contêiner flex — o elemento pai com display: flex. Elas controlam como todos os itens filhos são distribuídos e alinhados.

css
/* display: flex makes the element a block-level flex container.
   display: inline-flex makes it inline (sits in text flow). */
.nav {
  display: flex;
}

/* flex-direction — which way does the main axis run? */
.nav {
  flex-direction: row;         /* left to right (default)  */
  flex-direction: row-reverse; /* right to left            */
  flex-direction: column;      /* top to bottom            */
  flex-direction: column-reverse; /* bottom to top         */
}

/* flex-wrap — what happens when items overflow the container? */
.card-grid {
  flex-wrap: nowrap;       /* all items forced onto one line (default) */
  flex-wrap: wrap;         /* items wrap onto additional lines         */
  flex-wrap: wrap-reverse; /* items wrap in reverse order              */
}

/* gap — space between items. Modern approach; avoids margin hacks. */
.card-grid {
  gap: 1.5rem;             /* same in both directions              */
  gap: 1rem 2rem;          /* row-gap column-gap                   */
}

A propriedade gap merece menção especial. Antes de existir, o padrão comum era adicionar margens aos itens flex e depois cancelar as bordas externas com margens negativas. gap substitui tudo isso de forma limpa — use-o em todos os lugares.

css
/* justify-content — alignment on the MAIN axis */
.nav {
  justify-content: flex-start;    /* packed to start (default)              */
  justify-content: flex-end;      /* packed to end                          */
  justify-content: center;        /* packed to centre                       */
  justify-content: space-between; /* first/last at edges, equal gaps between */
  justify-content: space-around;  /* equal space around each item           */
  justify-content: space-evenly;  /* equal space between every gap          */
}

/* align-items — alignment on the CROSS axis (single line) */
.nav {
  align-items: stretch;   /* items fill cross-axis height (default)         */
  align-items: flex-start;/* items align to start of cross axis             */
  align-items: flex-end;  /* items align to end of cross axis               */
  align-items: center;    /* items centred on cross axis                    */
  align-items: baseline;  /* items aligned by their text baseline           */
}

/* align-content — cross-axis alignment when there are MULTIPLE lines
   (only takes effect with flex-wrap: wrap and enough items to wrap) */
.card-grid {
  flex-wrap: wrap;
  align-content: flex-start;    /* rows packed to top                       */
  align-content: center;        /* rows centred vertically                  */
  align-content: space-between; /* rows spread out with space between       */
}

Aqui está uma barra de navegação real combinando esses. O logo fica à esquerda, e os links de navegação são empurrados para a direita usando margin-left: auto — um truque clássico do Flexbox. A abordagem justify-content: space-between também funciona, mas a técnica de margem automática é mais flexível quando você tem mais de dois grupos.

css
/* Nav: logo left, links right */
.site-nav {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0 2rem;
  height: 64px;
  background: #1a1a2e;
}

.site-nav .logo {
  font-size: 1.25rem;
  font-weight: 700;
  color: #fff;
  text-decoration: none;
}

.site-nav .nav-links {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  margin-left: auto; /* pushes everything after it to the right */
  list-style: none;
  margin-top: 0;
  margin-bottom: 0;
  padding: 0;
}

.site-nav .nav-links a {
  color: #ccc;
  text-decoration: none;
  font-size: 0.9rem;
}

.site-nav .nav-links a:hover {
  color: #fff;
}

Propriedades dos Itens

Essas propriedades vão nos itens flex — os filhos diretos do contêiner flex. Elas controlam como itens individuais crescem, encolhem e se dimensionam.

  • flex-grow — quanto do espaço livre disponível este item reivindica. Padrão 0 (não crescer). Defina como 1 em um item e ele ocupa todo o espaço restante.
  • flex-shrink — quanto este item encolhe em relação aos outros quando não há espaço suficiente. Padrão 1. Defina como 0 para impedir que um item encolha.
  • flex-basis — o tamanho inicial do item antes de qualquer crescimento ou encolhimento. Pode ser um comprimento (250px, 30%) ou auto (usar o tamanho do conteúdo do item).
  • align-self — substitui align-items para um item específico. Aceita os mesmos valores: auto, flex-start, flex-end, center, baseline, stretch.
  • order — muda a ordem visual sem tocar no HTML. Padrão 0. Valores menores aparecem primeiro. Use com moderação — quebra a ordem de tabulação e causa problemas de acessibilidade para usuários de teclado e leitor de tela.
css
/* Classic sidebar + main content layout */
.app-layout {
  display: flex;
  min-height: 100vh;
}

.sidebar {
  flex: 0 0 280px; /* don't grow, don't shrink, always 280px wide */
  background: #f5f5f5;
  padding: 2rem 1.5rem;
}

.main-content {
  flex: 1; /* grow to fill all remaining space */
  padding: 2rem;
  min-width: 0; /* critical: prevents content overflow in flex children */
}

/* Responsive: stack vertically on mobile */
@media (max-width: 768px) {
  .app-layout {
    flex-direction: column;
  }

  .sidebar {
    flex: none; /* reset — don't use flex-basis on column layout */
  }
}
O problema do min-width: 0: Por padrão, itens flex não podem encolher abaixo do tamanho mínimo do conteúdo. Se você tem uma palavra longa ou uma tabela larga dentro de um item flex, ele vai transbordar em vez de quebrar. Adicionar min-width: 0 ao item flex resolve isso. Aparece constantemente na área de conteúdo principal em layouts de barra lateral.

A Abreviação flex Explicada

A abreviação flex compacta flex-grow, flex-shrink e flex-basis em uma declaração. A especificação W3C define alguns valores de palavras-chave que cobrem os casos comuns, e eles frequentemente são confundidos entre si.

css
/* flex: 1
   Expands to: flex-grow: 1; flex-shrink: 1; flex-basis: 0%
   Meaning: grow and shrink freely; start from zero (ignore content size).
   All items with flex: 1 share space equally, regardless of content.
   Most common choice for "fill available space". */
.tab { flex: 1; }

/* flex: auto
   Expands to: flex-grow: 1; flex-shrink: 1; flex-basis: auto
   Meaning: grow and shrink freely; start from the item's content size.
   Items with more content get more space — proportional, not equal. */
.column { flex: auto; }

/* flex: none
   Expands to: flex-grow: 0; flex-shrink: 0; flex-basis: auto
   Meaning: completely rigid — don't grow, don't shrink, stay at content size.
   Use for items that should never flex (icons, avatars, fixed labels). */
.avatar { flex: none; }

/* flex: 0 0 200px
   Explicit: don't grow, don't shrink, always exactly 200px.
   Same as writing out all three values. More readable for fixed-size items. */
.sidebar { flex: 0 0 200px; }

/* Practical difference: flex: 1 vs flex: auto in a tab bar
   With flex: 1  → all tabs are equal width regardless of label length
   With flex: auto → "Settings" tab is wider than "Home" tab */
.tabs { display: flex; }
.tab-equal  { flex: 1;    } /* equal width tabs     */
.tab-auto   { flex: auto; } /* content-sized tabs   */

Layouts Reais Comuns

Aqui estão quatro padrões que você usará regularmente — construídos com nada além de Flexbox.

css
/* 1. Sticky footer
   The footer always sits at the bottom, even on short pages.
   body (or .app-shell) becomes a column flex container. */
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
}

main {
  flex: 1; /* expands to push footer down */
}

footer {
  /* stays at the bottom */
}
css
/* 2. Centred modal / hero content
   Both axes centred — the Flexbox vertical-centring party trick. */
.hero {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  padding: 2rem;
  background: linear-gradient(135deg, #667eea, #764ba2);
}

.hero-content {
  max-width: 640px;
  text-align: center;
  color: #fff;
}
css
/* 3. Nav bar: logo left, links right */
.site-nav {
  display: flex;
  align-items: center;
  padding: 0 2rem;
  height: 64px;
}

.site-nav .nav-links {
  margin-left: auto; /* auto margin consumes all free space to its left */
  display: flex;
  gap: 1.5rem;
  list-style: none;
  padding: 0;
  margin-top: 0;
  margin-bottom: 0;
}
css
/* 4. Card row that wraps on mobile */
.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
}

.card {
  flex: 1 1 280px; /* grow and shrink, but never below 280px wide */
  background: #fff;
  border-radius: 8px;
  padding: 1.5rem;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

/* On wide screens: 3-4 cards per row.
   On narrow screens: cards wrap into their own rows automatically.
   No media query needed for the wrap itself — flex-wrap handles it. */

Flexbox vs Grid — Quando Usar Qual

Esta questão aparece constantemente, e a resposta é mais simples do que a maioria dos artigos sugere: Flexbox é para layouts unidimensionais. CSS Grid é para layouts bidimensionais. Se você está dispondo itens em uma única linha ou uma única coluna — uma barra de navegação, um grupo de botões, uma linha de cartões — o Flexbox é a ferramenta certa. Se você precisa controlar linhas e colunas simultaneamente — um layout de página completa, um mosaico de fotos, uma grade de formulário — use o Grid.

Na prática, você usará ambos no mesmo projeto. O Grid lida com a estrutura de nível de página (cabeçalho, barra lateral, principal, rodapé). O Flexbox lida com os componentes dentro dessas regiões (a barra de navegação, o conteúdo do cartão, o cluster de botões dentro de um modal). Eles se complementam em vez de competir.

A zona cinzenta: grades de cartões que devem ter linhas de igual altura com itens alinhados em colunas. O Flexbox com flex-wrap: wrap pode fazer isso, mas itens na mesma linha visual não têm relação entre si — suas alturas são independentes. O dimensionamento implícito de linhas do Grid lida com isso automaticamente. Se você precisa que os cartões em uma linha envolvida tenham todos a mesma altura E tenham seus elementos internos alinhados entre cartões, o Grid é mais limpo.

Conclusão

O modelo mental do Flexbox é: escolha uma direção, entenda quais propriedades controlam qual eixo, depois decida se os itens devem crescer, encolher ou permanecer fixos. Uma vez que isso clica, a folha de referência se torna uma consulta — não uma muleta. O guia MDN de Flexbox é a melhor referência para casos extremos, e o guia completo CSS-Tricks continua sendo a folha de referência visual mais útil por aí. Para uso em produção, o suporte de navegadores é essencialmente universal — sem prefixos necessários. A especificação W3C vale uma leitura rápida se você encontrar um caso extremo genuinamente confuso — o algoritmo é documentado com precisão e responde à maioria das perguntas "por que isso se comporta assim".