Tem uma pergunta que sempre aparece: “devo usar Grid ou Flexbox?”. E a resposta correta é: depende. Mas calma, não vou enrolar. Vou te explicar exatamente quando usar cada um, sem evangelismo de framework, sem “ah, mas o Grid é mais poderoso para layouts complexos”. A real é: os dois são bons, os dois têm seu lugar, e saber quando usar cada um te poupa muita dor de cabeça.

Eu passei anos usando só Flexbox pra tudo. Funcionava? Funcionava. Mas tinha hora que eu ficava ali criando wrapper em cima de wrapper, ajeitando flex-direction, mudando justify-content e align-items pra um lado e pro outro (até hoje não sei de cabeça qual usar dependendo da direção do flex hehe)… até que um dia eu parei e pensei: “tá, mas será que não tem um jeito mais simples?”. E tinha. Grid. São ferramentas diferentes pra problemas diferentes. E quanto mais cedo você entende isso, mais rápido você para de sofrer.

A diferença que importa

Flexbox é pra uma dimensão. Linha OU coluna. Você quer alinhar coisas numa direção? Flexbox. Simples assim.

Grid é pra duas dimensões. Linha E coluna. Você quer controlar o layout completo, tipo aqueles layouts de 12 colunas? Grid. Não é sobre qual é melhor. É sobre qual resolve o seu problema de forma mais direta.

Quando usar Flexbox

1. Navegação/Menu

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

Pronto. Itens na horizontal, alinhados no centro, com espaço entre eles. Você não precisa de Grid pra isso.

2. Centralizar algo (de verdade)

CSS
.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

Esse é o clássico. Centraliza vertical e horizontal sem gambiarra. Sem position: absolute, sem transform, sem rezar.

3. Cards em linha que quebram

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

.card {
  flex: 1 1 300px;
}

Os cards vão se ajustando conforme o espaço disponível. Se couber 3, fica 3. Se couber 2, fica 2. Simples e responsivo.

4. Layouts de formulário

CSS
.form-row {
  display: flex;
  gap: 1rem;
}

.form-field {
  flex: 1;
}

Campos lado a lado, ocupando o espaço igualmente. Funciona, é limpo, não precisa de mais nada.

Quando usar Grid

1. Layout completo da página

CSS
.page {
  display: grid;
  grid-template-areas:
    "header header header"
    "sidebar main aside"
    "footer footer footer";
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

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

Olha isso. Você vê a estrutura inteira só olhando o código. Header, sidebar, conteúdo principal, aside, footer. Tudo no lugar. Tenta fazer isso com Flexbox sem criar 15 wrappers.

2. Galeria de imagens

CSS
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1rem;
}

As imagens se organizam sozinhas. Se couber 4, fica 4. Se couber 3, fica 3. E todas com o mesmo tamanho. Sem JavaScript, sem mágica.

3. Dashboard/Admin

CSS
.dashboard {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
}

Aqueles cards de estatísticas, gráficos, widgets… Grid resolve. Os elementos se encaixam certinho, sempre preenchendo o espaço disponível.

4. Quando você precisa sobrepor elementos

CSS
.card {
  display: grid;
  grid-template-areas: "content";
}

.card-image,
.card-overlay {
  grid-area: content;
}

Os dois elementos ocupam o mesmo espaço. Sem position: absolute, sem cálculo manual. Grid empilha tudo na mesma célula.

E quando os dois funcionam?

Às vezes dá pra resolver com qualquer um. Exemplo: uma lista de cards. Você pode fazer com Flexbox (como mostrei antes) ou com Grid. Nesse caso, vai do que você tá mais confortável.

Mas tem uma regra que funciona bem:

  • Se você tá pensando em termos de “linha” ou “coluna”, vai de Flexbox.
  • Se você tá pensando em “linhas E colunas”, vai de Grid.

O exemplo que fecha a conta

Vamos fazer uma section de blog típica: 3 posts em destaque em cima, lista de posts normais embaixo.

Com Flexbox (vai ficar verboso)

CSS
.blog-section {
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

.featured {
  display: flex;
  gap: 1rem;
}

.featured-post {
  flex: 1;
}

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

.post {
  flex: 1 1 calc(33.333% - 1rem);
}

Funciona, mas olha quanta classe. E você ainda tem que calcular manualmente o tamanho dos posts considerando o gap.

Com Grid (mais limpo)

CSS
.blog-section {
  display: grid;
  gap: 2rem;
}

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

.post-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1rem;
}

Mesma coisa, menos código, mais claro. O Grid cuida do espaçamento sozinho.

Dá pra misturar?

Sim, e é isso que você deveria fazer. Grid pro layout macro, Flexbox pra componentes pequenos.

CSS
.page {
  display: grid;
  grid-template-columns: 250px 1fr;
  gap: 2rem;
}

.sidebar nav {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.card-actions {
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
}

Cada um fazendo o que faz de melhor.

No fim das contas…

Não existe “vencedor”. Grid não mata Flexbox. Flexbox não é inútil. São ferramentas diferentes.

Use Flexbox quando você tá organizando coisas numa direção só. Use Grid quando você precisa controlar linhas e colunas ao mesmo tempo. E quando tiver dúvida, testa os dois. Às vezes você só descobre qual funciona melhor quando bota a mão no código.

E sinceramente? Quanto menos você brigar com o CSS e mais você usar a ferramenta certa pro problema certo, mais rápido você vai entregar. E é isso que importa no final.