CSS Grid vs Flexbox: quando usar cada um
Grid é bidimensional, Flexbox é unidimensional. A escolha certa entre os dois depende do que o layout está tentando fazer — não de preferência pessoal.
Todo projeto começa igual: alguém usa Flexbox pra tudo. Funciona até aparecer aquele layout com coluna lateral fixa, header e conteúdo principal que precisa se ajustar em altura — aí vira uma série de hacks com flex-wrap, align-self e min-height que ninguém consegue mais manter. A pergunta que deveria ter sido feita antes: esse layout é uma linha ou uma grade?
A resposta para isso é o divisor entre Flexbox e CSS Grid.
A regra que resume tudo: 1D vs 2D
Flexbox é um modelo de layout unidimensional — você distribui itens em uma direção: linha ou coluna. Grid é bidimensional — você posiciona itens em linhas e colunas ao mesmo tempo.
Essa distinção não é marketing de especificação. Ela determina o que cada um consegue fazer de forma natural, sem hack.
Com Flexbox, quando você define flex-direction: row, os itens se organizam numa linha. Você controla espaçamento, alinhamento e wrapping — mas cada linha é independente das outras. O Flexbox não tem como fazer um item de uma linha "saber" a largura dos itens na linha de baixo.
Com Grid, você define as trilhas (colunas e linhas) e os itens se encaixam nessa grade. Uma célula na linha 2 fica perfeitamente alinhada com a célula da linha 1 porque ambas compartilham a mesma coluna.
/* Flexbox: itens em linha, sem controle de coluna entre linhas */
.nav {
display: flex;
gap: 16px;
align-items: center;
}
/* Grid: layout com colunas e linhas definidas */
.page-layout {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr auto;
min-height: 100vh;
}
Quando usar Flexbox
Flexbox brilha em componentes onde o fluxo é linear e o conteúdo determina o espaço.
Bons casos de uso:
- Barra de navegação com logo e links
- Botão com ícone + texto lado a lado
- Lista de tags / chips
- Card com conteúdo empilhado verticalmente
- Centralizar um elemento no container (o clássico
justify-content: center; align-items: center) - Distribuir espaço entre itens com
justify-content: space-between
/* centralizar vertical e horizontal — 3 linhas */
.card-center {
display: flex;
justify-content: center;
align-items: center;
}
/* botão com ícone */
.btn {
display: flex;
align-items: center;
gap: 8px;
}
/* header com logo e nav em extremos opostos */
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 24px;
}
O sinal de que Flexbox é a escolha certa: você está pensando em uma direção (ou horizontal, ou vertical), e os itens podem ter tamanhos diferentes sem problema.
O sinal de que você está forçando: você precisa que itens em linhas diferentes se alinhem entre si. Isso é o trabalho do Grid.
Quando usar CSS Grid
Grid é para layouts onde múltiplos itens precisam se alinhar em dois eixos — onde a grade importa, não só o fluxo.
Bons casos de uso:
- Layout de página (header, sidebar, main, footer)
- Grid de cards com altura uniforme por linha
- Galeria de imagens
- Dashboard com widgets em posições fixas
- Formulários com labels e inputs alinhados em colunas
/* layout clássico de aplicação */
.app {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr 48px;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
/* grid de cards responsivo sem media query */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
O segundo exemplo é um dos truques mais práticos do CSS moderno: auto-fill + minmax cria um grid responsivo que adiciona colunas conforme o espaço disponível, sem uma única @media query.
Combinando os dois — a abordagem real
O mais comum em projetos reais não é escolher um ou outro. É usar Grid para a estrutura macro e Flexbox para os componentes internos.
Um exemplo de layout de aplicação completo:
/* Grid define a estrutura geral da página */
.app {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr;
height: 100vh;
}
/* Flexbox organiza os itens dentro do header */
.app-header {
grid-column: 1 / -1;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
}
/* Flexbox também dentro do card */
.card {
display: flex;
flex-direction: column;
gap: 12px;
padding: 16px;
}
.card-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: auto; /* empurra pro fim do card */
}
O Grid não sabe (nem precisa saber) como os itens internos do header se organizam. O Flexbox não sabe (nem precisa saber) que o header ocupa grid-column: 1 / -1. Cada ferramenta faz o que faz melhor.
Por que não usar só Grid para tudo?
A tentação oposta também existe — depois de aprender Grid, usá-lo pra tudo. O problema é que Grid é mais verboso para fluxos lineares simples. Centralizar um botão com ícone com Grid:
.btn {
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
gap: 8px;
}
Versus Flexbox:
.btn {
display: flex;
align-items: center;
gap: 8px;
}
Funciona nos dois, mas o Grid aqui é ruído. A intenção é menos clara — você está criando uma grade de duas colunas quando só queria alinhar dois itens em linha. Código que anuncia a intenção é mais fácil de manter.
Além disso, Grid tem comportamento menos intuitivo com conteúdo dinâmico em alguns casos — especialmente quando o número de itens varia e você quer que cada item ocupe o espaço que precisa, não uma célula da grade. Flexbox com flex-wrap é mais natural para esses casos.
Suporte a browsers: sem preocupação em 2026
Grid e Flexbox têm suporte acima de 97% em todos os browsers modernos. Se o projeto não precisa suportar IE11 (que oficialmente morreu em 2022), você pode usar qualquer feature de CSS Grid Level 2 — incluindo subgrid, que finalmente chegou ao Chrome 117 e resolveu o alinhamento de grids aninhados.
subgrid é o que você usa quando tem um container grid e quer que os itens filhos participem das trilhas do pai, em vez de criar uma grade própria:
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto;
}
.card {
display: grid;
grid-row: span 3;
grid-template-rows: subgrid; /* filhos usam as trilhas do pai */
}
Isso garante que o título, a imagem e o rodapé de todos os cards fiquem na mesma linha horizontal, mesmo com conteúdo de tamanho diferente — sem JavaScript, sem altura fixa.
Se você está montando grids mais elaborados e quer visualizar o output em tempo real — CSS e Tailwind ao mesmo tempo —, uso o Gerador CSS Grid para prototipar antes de codar. Especialmente útil para testar grid-template-areas com nomes antes de commitar na estrutura final.
O post sobre HTML semântico cobre a estrutura de header, main, aside e footer — os elementos que você normalmente mapeia para as áreas do Grid. Faz sentido ler os dois juntos: semântica define o significado, Grid define o posicionamento.
Perguntas frequentes
Posso usar Flexbox e Grid no mesmo elemento?
Não diretamente — display: flex e display: grid são mutuamente exclusivos no mesmo elemento. Mas um elemento pode ser filho de um Grid e pai de um Flexbox ao mesmo tempo. Isso é exatamente o padrão de combinação descrito acima: Grid no container externo, Flexbox nos componentes internos.
CSS Grid substitui Flexbox?
Não. Eles resolvem problemas diferentes. Grid é melhor para layout de página e alinhamento bidimensional. Flexbox é melhor para fluxo linear de componentes. Na prática, você vai usar os dois — e quanto mais você usa, mais óbvio fica qual dos dois é a ferramenta certa para cada situação.
Por que meu Grid não alinha os itens da forma esperada?
A causa mais comum é não definir as trilhas explicitamente. Quando você só usa display: grid sem grid-template-columns, o browser cria uma grade de uma coluna implícita. Defina as colunas com grid-template-columns e, se necessário, as linhas com grid-template-rows. A outra causa comum é esquecer que gap não afeta as margens externas — ele só adiciona espaço entre as células.
Quando auto-fill e quando auto-fit?
auto-fill cria colunas vazias se houver espaço disponível. auto-fit expande as colunas existentes para preencher o espaço. A diferença fica visível quando você tem poucos itens: com auto-fill, as células vazias ocupam o espaço; com auto-fit, os itens existentes crescem. Para grids de cards onde você quer que os itens cresçam pra preencher a linha, auto-fit é geralmente a escolha certa.
A escolha é sobre intenção, não sobre preferência
Flexbox e Grid não são rivais — são ferramentas com escopos diferentes. A questão nunca é "qual é melhor", é "o que esse layout está tentando fazer?".
Se a resposta for "distribuir itens em uma direção, com espaçamento e alinhamento", Flexbox. Se a resposta for "posicionar elementos em uma grade com controle de linhas e colunas", Grid. Se a resposta for "estruturar a página toda", provavelmente Grid para o macro e Flexbox para os componentes.
A confusão acontece quando você usa Flexbox para fazer o trabalho de Grid — empilhando hacks de flex-wrap e width percentuais onde grid-template-columns seria três palavras. Reconhecer o padrão antes de começar a codar poupa tempo e poupa o dev que vai manter isso no futuro.
- 01 O que é JSON e como esse formato funciona Entenda o que é JSON, seus seis tipos de dados, sintaxe obrigatória e onde o formato é usado — com exemplos reais em JavaScript, Python e Go.
- 02 Como os LLMs geram respostas: tokens, predição e sampling explicados Tokenização, predição autorregressiva, temperatura e Top-P: a mecânica interna de como modelos de linguagem transformam um prompt em texto.