CSS Grid vs Flexbox: quando usar cada um (sem chute e sem sofrimento)
← Voltar para Codeshort

CSS Grid vs Flexbox: quando usar cada um (sem chute e sem sofrimento)

Entenda o modelo mental por trás do Grid e do Flexbox, veja os erros mais comuns com exemplos reais de código e tome decisões de layout com critério — não na tentativa e erro.

DC
Dev Code Software
17 de abril de 2026·10 min de leitura

O ciclo do chute e como sair dele

Você abre o DevTools, tenta display: flex, não fica certo, troca para display: grid, mexe em algumas propriedades, volta pro flex, joga um position: absolute no desespero — e de alguma forma aquilo funciona. Você fecha o laptop sem entender exatamente por quê.

Esse é o ciclo do chute. E ele persiste porque a maioria dos tutoriais ensina propriedades, não modelos mentais. Você aprende o que justify-content faz, mas nunca aprende quando cada ferramenta faz sentido de verdade.

Este artigo corrige isso. Sem lista de propriedades que você já conhece. Sem comparação superficial. O foco é: como você pensa sobre layout antes de escrever a primeira linha de CSS.


O modelo mental que ninguém explica direito

A pergunta errada é: "Grid ou Flexbox?"

A pergunta certa é: "Meu problema é de distribuição ou de estrutura?"

Flexbox resolve distribuição em uma dimensão: como organizar itens ao longo de um eixo — horizontal ou vertical. O layout emerge do tamanho dos itens. Você não define onde cada coisa vai; você define as regras e deixa o browser calcular.

Grid resolve estrutura em duas dimensões: linhas e colunas ao mesmo tempo, com controle explícito do espaço. Você define a estrutura primeiro, depois posiciona os itens nela.

Não é sobre qual é mais poderoso. É sobre qual corresponde ao problema que você está resolvendo agora.

Uma analogia que ajuda a fixar: Flexbox é como organizar livros numa prateleira — você define a ordem e o espaçamento entre eles. Grid é como projetar a estante inteira — você define quantas prateleiras existem, qual a altura de cada uma, e onde cada livro vai.


Flexbox: domínio de um eixo

Flexbox brilha em qualquer situação onde você tem um grupo de itens e precisa distribuí-los ou alinhá-los numa direção. Navbar, lista de botões, breadcrumb, grupo de tags — todos são casos naturais para Flex.

.navbar {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.navbar__logo {
  margin-right: auto;
}

O margin-right: auto aqui é um dos truques mais elegantes do Flexbox: ele consome todo o espaço disponível depois do logo, empurrando o restante dos itens para a direita. Nada de position: absolute, nada de float.

.actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

O flex-wrap: wrap resolve um problema clássico: em telas menores, os botões quebram para a próxima linha em vez de vazar o container.

O trio que a maioria usa errado

flex-grow, flex-shrink e flex-basis são o coração do Flexbox — e os responsáveis pela maioria dos bugs de layout que você já debugou sem entender.

.item {
  flex: 1;
}

Parece simples. Mas flex: 1 é um shorthand que expande para:

.item {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0%;
}

O detalhe crítico é o flex-basis: 0%. Isso faz o item começar do zero antes de distribuir o espaço disponível — ignorando o tamanho do conteúdo interno. Já flex: 1 1 auto usa flex-basis: auto, o que significa que o item começa do tamanho do seu conteúdo e depois cresce.

Na prática: se seus itens têm conteúdos de tamanhos muito diferentes, flex: 1 vai dar larguras iguais a todos. flex: 1 1 auto vai dar proporcionalmente mais espaço para os itens que já são maiores. Nenhum está errado — depende do que você quer.


Grid: estrutura nas duas dimensões

Grid é para quando você pensa em layout de página, não em alinhamento de itens. Você define a estrutura primeiro — quantas colunas, quantas linhas, quais áreas existem — e depois posiciona os itens.

.page {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: 60px 1fr 50px;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  min-height: 100vh;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

O grid-template-areas é uma das propriedades mais subestimadas do CSS. Você lê o layout direto no código — sem cálculos, sem comentários explicando o que cada classe faz. Qualquer desenvolvedor que abrir esse arquivo vai entender a estrutura em segundos.

O padrão responsivo que elimina media queries

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.5rem;
}

Essa combinação de auto-fill com minmax cria um grid que se adapta sozinho à largura disponível. Em telas largas, aparecem quatro cards por linha. Em telas médias, três. Em mobile, um. Tudo sem uma única @media query.

Como funciona: minmax(280px, 1fr) significa que cada coluna tem no mínimo 280px e no máximo 1 fração do espaço disponível. O auto-fill instrui o browser a criar quantas colunas couberem com esse tamanho. O resultado é um grid fluido que responde à viewport como se tivesse breakpoints, mas sem nenhum.


Erros reais de devs intermediários (com código)

1. Usar Flex para fazer grid de cards

.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.card {
  flex: 1 1 calc(33% - 1rem);
}

O calc(33% - 1rem) aqui é um sinal claro de que a ferramenta errada está sendo usada. Você está manualmente calculando o que o Grid faria automaticamente:

.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

Mais curto, mais claro, e sem a chance de o calc quebrar quando o gap mudar.

2. Centralização vertical que não funciona

.container {
  display: flex;
  align-items: center;
}

Se o container não tem altura explícita, align-items: center não tem efeito visível — não há espaço vertical para distribuir. O container tem exatamente a altura do conteúdo. Para centralizar de verdade:

.container {
  display: flex;
  align-items: center;
  min-height: 100vh;
}

Ou, com Grid:

.container {
  display: grid;
  place-items: center;
  min-height: 100vh;
}

3. position: absolute dentro de Grid desnecessariamente

Quando você adiciona position: absolute a um item dentro de um Grid container, esse item sai do fluxo do grid. Ele não ocupa célula nenhuma, não influencia o tamanho das colunas e pode sobrepor outros itens silenciosamente. Na maioria dos casos, o que você realmente queria era grid-column e grid-row:

.destaque {
  grid-column: 1 / -1;
  grid-row: 2;
}

Isso posiciona o item com precisão sem tirá-lo do fluxo.

4. Confundir justify-content com justify-items

PropriedadeAge sobreQuando usar
justify-contentO container inteiroDistribuir espaço sobrando entre colunas
justify-itemsCada item individualmenteAlinhar conteúdo dentro da célula
align-contentLinhas do grid no containerDistribuir espaço entre linhas
align-itemsItens no eixo cruzadoAltura de cada item dentro da célula

A confusão mais comum: usar justify-content: center esperando centralizar o conteúdo de cada célula. Isso centraliza as colunas dentro do container — que só tem efeito se o total das colunas for menor que o container. Para centralizar dentro de cada célula, é justify-items: center.


Como decidir em menos de 10 segundos

Faça uma pergunta: meu layout tem uma ou duas dimensões?

Uma dimensão → Flexbox:

  • Navbar com logo e links
  • Linha de botões de ação
  • Lista horizontal de tags
  • Breadcrumb
  • Rodapé simples com itens lado a lado

Duas dimensões → Grid:

  • Layout de página com header, sidebar, main e footer
  • Galeria de imagens
  • Grid de cards de produto
  • Dashboard com widgets
  • Qualquer coisa onde você controla linhas e colunas simultaneamente

Centralizar um único elemento? Tanto faz:

.center-flex {
  display: flex;
  justify-content: center;
  align-items: center;
}

.center-grid {
  display: grid;
  place-items: center;
}

Ambos funcionam. Se o container já é um Grid por outro motivo, use place-items. Se já é Flex, use o par justify-content + align-items. Não mude a ferramenta só pra centralizar.


Usando os dois juntos: o padrão que funciona

Em qualquer interface real, você vai usar Grid e Flexbox simultaneamente — em níveis diferentes da hierarquia. Não existe conflito. Existe divisão de responsabilidade:

Grid define a macro-estrutura da página. Flexbox organiza os itens dentro de cada região.

.layout {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-areas: "sidebar content";
  min-height: 100vh;
}

.sidebar {
  grid-area: sidebar;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1.5rem;
}

.content {
  grid-area: content;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1.5rem;
  align-content: start;
  padding: 1.5rem;
}

O content aqui é ao mesmo tempo um item de Grid (definido pelo .layout) e um Grid container para os cards internos. Isso é composição de layout — e é exatamente como interfaces de produção são construídas.

O align-content: start no .content evita que as linhas do grid se estiquem para preencher o container quando há poucas linhas — um detalhe que faz diferença em layouts com poucos cards.


FAQ

Grid vai substituir o Flexbox? Não. São ferramentas com propósitos diferentes. O suporte dos dois está acima de 97% dos browsers. Nenhum vai substituir o outro — eles se complementam.

Por que meu align-items não funciona no Flex? O container não tem altura suficiente. align-items alinha no eixo cruzado — se o container tem só a altura do conteúdo, não há espaço vertical a distribuir. Adicione height ou min-height.

Posso usar Grid para alinhar uma linha de botões? Tecnicamente sim, mas é overkill. Para distribuição linear sem estrutura de grid, Flex é mais semântico e mais fácil de manter. Use a ferramenta certa para o problema certo.

gap funciona igual no Flex e no Grid? Sim. O comportamento é o mesmo desde que gap foi padronizado (antes era grid-gap exclusivo do Grid). A diferença importante: gap não adiciona espaço nas bordas externas — diferente de margin.

fr funciona com minmax? Sim, e é uma das combinações mais poderosas do CSS moderno. minmax(200px, 1fr) garante que a coluna nunca fique menor que 200px, mas pode crescer para preencher o espaço disponível. É a base do padrão responsivo sem media query.

Quando auto-fill e auto-fit se comportam diferente? Quando há menos itens do que colunas cabem: auto-fill mantém as colunas vazias (espaço reservado), auto-fit colapsa as colunas vazias e deixa os itens existentes preencherem o espaço. Para grids de cards, auto-fill geralmente é o comportamento desejado.


Próximos passos

Teoria sem prática não muda como você escreve código. Três exercícios concretos para fixar o que você leu:

1. Audite um projeto existente. Abra o CSS de algum projeto seu e identifique três lugares onde você usou Flex quando Grid seria mais adequado — ou o contrário. Refatore um deles e veja se o código fica menor.

2. Implemente um layout com grid-template-areas. Pegue qualquer layout de página com header, sidebar e footer e implemente usando grid-template-areas. A clareza visual que isso traz muda como você pensa em estrutura de página.

3. Teste o padrão auto-fill + minmax. Crie um grid de cards com esse padrão e redimensione a janela devagar. Veja como as colunas se reorganizam sem nenhum breakpoint. Depois tente o mesmo com auto-fit e observe a diferença quando sobram colunas.

Esses três exercícios levam menos de uma hora e valem mais do que ler mais dez artigos sobre o assunto.