- O ciclo do chute e como sair dele
- O modelo mental que ninguém explica direito
- Flexbox: domínio de um eixo
- Grid: estrutura nas duas dimensões
- Erros reais de devs intermediários (com código)
- Como decidir em menos de 10 segundos
- Usando os dois juntos: o padrão que funciona
- FAQ
- Próximos passos
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
| Propriedade | Age sobre | Quando usar |
|---|---|---|
justify-content | O container inteiro | Distribuir espaço sobrando entre colunas |
justify-items | Cada item individualmente | Alinhar conteúdo dentro da célula |
align-content | Linhas do grid no container | Distribuir espaço entre linhas |
align-items | Itens no eixo cruzado | Altura 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.