CSS Flexbox vs Grid: Quando Usar Cada Um
· 12 min de leitura
Índice
- Fundamentos do Flexbox (Layout 1D)
- Fundamentos do Grid (Layout 2D)
- Comparação Lado a Lado
- Quando Usar Flexbox
- Quando Usar Grid
- Exemplos de Layouts Reais
- Combinando Flexbox e Grid
- Considerações de Performance
- Padrões de Design Responsivo
- Suporte dos Navegadores
- Erros Comuns a Evitar
- Perguntas Frequentes
Escolher entre CSS Flexbox e Grid pode parecer avassalador, especialmente quando ambos parecem capazes de resolver os mesmos problemas de layout. A verdade é que eles são projetados para propósitos diferentes, e entender seus pontos fortes vai te tornar um desenvolvedor mais eficaz.
Este guia detalha tudo o que você precisa saber sobre Flexbox e Grid, desde conceitos fundamentais até aplicações do mundo real. Ao final, você saberá exatamente qual ferramenta usar em qualquer cenário de layout.
Fundamentos do Flexbox (Layout 1D)
Flexbox é projetado para layouts unidimensionais — organizando itens em uma única linha ou coluna. Ele se destaca na distribuição de espaço e alinhamento de itens ao longo de um eixo, sendo perfeito para barras de navegação, grupos de botões e conteúdo que flui em uma única direção.
Conceitos Fundamentais
Todo layout Flexbox tem um flex container (pai) e flex items (filhos). O container controla a direção, quebra de linha e alinhamento de seus itens:
/* O flex container */
.container {
display: flex;
flex-direction: row; /* row | row-reverse | column | column-reverse */
justify-content: center; /* Alinhamento do eixo principal */
align-items: center; /* Alinhamento do eixo transversal */
gap: 1rem; /* Espaço entre itens */
flex-wrap: wrap; /* Permitir que itens quebrem para a próxima linha */
}
/* Flex items */
.item {
flex: 1; /* Crescer para preencher o espaço disponível */
/* Atalho para: flex-grow: 1; flex-shrink: 1; flex-basis: 0; */
}
.item-fixed {
flex: 0 0 200px; /* Não crescer, não encolher, 200px de largura */
}
Entendendo os Eixos Principal e Transversal
A chave para dominar o Flexbox é entender seus dois eixos. O eixo principal segue na direção definida por flex-direction (horizontal para row, vertical para column). O eixo transversal é perpendicular a ele.
Este sistema de eixos determina quais propriedades controlam quais dimensões. justify-content sempre funciona no eixo principal, enquanto align-items funciona no eixo transversal.
Propriedades de Alinhamento
/* Eixo principal (horizontal na direção row) */
.container {
justify-content: flex-start; /* Padrão: agrupar itens no início */
justify-content: flex-end; /* Agrupar itens no final */
justify-content: center; /* Centralizar itens */
justify-content: space-between;/* Espaço igual entre itens */
justify-content: space-around; /* Espaço igual ao redor dos itens */
justify-content: space-evenly; /* Espaço igual em todos os lugares */
}
/* Eixo transversal (vertical na direção row) */
.container {
align-items: stretch; /* Padrão: esticar para preencher o container */
align-items: flex-start; /* Alinhar ao topo */
align-items: flex-end; /* Alinhar ao fundo */
align-items: center; /* Centralizar verticalmente */
align-items: baseline; /* Alinhar linhas de base do texto */
}
A Propriedade Flex Explicada
A propriedade flex é um atalho para três propriedades: flex-grow, flex-shrink e flex-basis. Entender cada uma individualmente ajuda você a escrever layouts mais precisos.
- flex-grow: Quanto o item deve crescer em relação a outros itens (padrão: 0)
- flex-shrink: Quanto o item deve encolher quando o espaço é limitado (padrão: 1)
- flex-basis: O tamanho inicial antes de crescer ou encolher (padrão: auto)
.item-grow {
flex: 1; /* Equivalente a: 1 1 0% */
}
.item-fixed {
flex: 0 0 200px; /* Não crescer ou encolher, permanecer em 200px */
}
.item-shrink {
flex: 0 1 auto; /* Não crescer, mas pode encolher se necessário */
}
Dica profissional: Use flex: 1 quando quiser que os itens compartilhem o espaço igualmente, e flex: 0 0 auto quando quiser que os itens mantenham seu tamanho natural sem crescer ou encolher.
Fundamentos do Grid (Layout 2D)
CSS Grid é construído para layouts bidimensionais — controlando linhas e colunas simultaneamente. É a escolha ideal para layouts de página, grades de cards e qualquer design onde você precisa de controle preciso sobre ambas as dimensões.
Conceitos Fundamentais
Layouts Grid consistem em um grid container e grid items. Diferente do Flexbox, Grid permite definir trilhas explícitas (linhas e colunas) e posicionar itens em qualquer lugar dentro dessa estrutura:
/* O grid container */
.container {
display: grid;
grid-template-columns: 200px 1fr 1fr; /* 3 colunas */
grid-template-rows: auto 1fr auto; /* 3 linhas */
gap: 1rem; /* Espaço entre células */
grid-auto-flow: row; /* Como itens auto-posicionados fluem */
}
/* Grid items */
.item {
grid-column: 1 / 3; /* Expandir da linha de coluna 1 até 3 */
grid-row: 1 / 2; /* Ocupar primeira linha */
}
.item-area {
grid-area: header; /* Posicionar em área nomeada */
}
Entendendo Linhas e Trilhas do Grid
Grid cria linhas numeradas entre trilhas. Um grid de 3 colunas tem 4 linhas verticais (1, 2, 3, 4). Itens são posicionados especificando entre quais linhas eles se expandem.
Trilhas são os espaços entre linhas — suas colunas e linhas reais. Você pode dimensioná-las com unidades fixas (px), unidades flexíveis (fr) ou dimensionamento baseado em conteúdo (auto, min-content, max-content).
A Unidade FR
A unidade fr é o superpoder do Grid. Ela representa uma fração do espaço disponível, distribuindo-o proporcionalmente entre as trilhas:
.container {
grid-template-columns: 1fr 2fr 1fr; /* Coluna do meio recebe 2x o espaço */
grid-template-columns: 200px 1fr; /* Barra lateral fixa, conteúdo flexível */
grid-template-columns: repeat(3, 1fr); /* Três colunas iguais */
}
Áreas Nomeadas do Grid
O recurso de áreas de template do Grid permite criar layouts usando sintaxe semelhante a arte ASCII, tornando layouts complexos legíveis:
.container {
display: grid;
grid-template-areas:
"header header header"
"sidebar content content"
"footer footer footer";
grid-template-columns: 200px 1fr 1fr;
grid-template-rows: auto 1fr auto;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer { grid-area: footer; }
Auto-Posicionamento e Fluxo Automático do Grid
Grid pode posicionar automaticamente itens que você não posiciona explicitamente. A propriedade grid-auto-flow controla se os itens preenchem linhas primeiro (padrão) ou colunas primeiro:
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: dense; /* Preencher lacunas com itens menores */
}
Dica profissional: Use grid-auto-flow: dense para layouts tipo alvenaria onde você quer preencher lacunas, mas esteja ciente de que isso pode mudar a ordem visual dos itens, potencialmente afetando a acessibilidade.
Comparação Lado a Lado
Vamos comparar Flexbox e Grid em dimensões-chave para entender suas diferenças fundamentais:
| Recurso | Flexbox | Grid |
|---|---|---|
| Dimensionalidade | Unidimensional (linha OU coluna) | Bidimensional (linhas E colunas) |
| Orientado a conteúdo | Sim - itens controlam seu tamanho | Não - container define a estrutura |
| Direção do layout | Um eixo por vez | Ambos os eixos simultaneamente |
| Posicionamento de itens | Sequencial (ordem do código) | Posicionamento explícito possível |
| Alinhamento | Poderoso em um único eixo | Poderoso em ambos os eixos |
| Suporte a gap | Sim (navegadores modernos) | Sim (desde o início) |
| Melhor para | Componentes, navegação, barras de ferramentas | Layouts de página, grades de cards, dashboards |
| Curva de aprendizado | Moderada | Mais íngreme inicialmente |
Diferenças Conceituais
A diferença fundamental se resume ao controle. Flexbox é de dentro para fora — itens influenciam o layout com base no tamanho do conteúdo. Grid é de fora para dentro — você define a estrutura primeiro, depois coloca o conteúdo nela.
Pense no Flexbox como uma régua flexível que se ajusta ao que você está medindo. Grid é mais como papel quadriculado onde você decide a estrutura antecipadamente.
| Cenário | Abordagem Flexbox | Abordagem Grid |
|---|---|---|
| Barra de navegação | Encaixe natural - itens em uma linha | Exagero - estrutura demais |
| Grade de cards | Possível mas quebra de linha estranha | Perfeito - linhas e colunas explícitas |
| Layout de formulário | Bom para formulários simples | Melhor para formulários complexos multi-coluna |
| Layout de página | Requer aninhar múltiplos containers | Um único container pode lidar com isso |
| Centralizar conteúdo | Excelente - simples e intuitivo | Também excelente - place-items: center |
Quando Usar Flexbox
Flexbox brilha em cenários onde o conteúdo flui em uma única direção e os itens precisam se adaptar ao espaço disponível. Aqui estão as situações onde Flexbox é sua melhor escolha:
Barras de Navegação e Menus
Componentes de navegação são o exemplo perfeito para Flexbox. Itens fluem naturalmente em uma linha, e você frequentemente quer que eles distribuam o espaço uniformemente ou se alinhem em extremos opostos:
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
}
Grupos de Botões e Barras de Ferramentas
Quando você tem uma coleção de botões ou ferramentas que devem ficar lado a lado, Flexbox lida com o espaçamento e alinhamento perfeitamente:
.button-group {
display: flex;
gap: 0.5rem;
}
.toolbar {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 1rem;
}
Objetos de Mídia
O padrão clássico de objeto de mídia (imagem de um lado, conteúdo do outro) é trivial com Flexbox:
.media {
display: flex;
gap: 1rem;
}
.media-image {
flex: 0 0 100px; /* Imagem de largura fixa */
}
.media-content {
flex: 1; /* Conteúdo ocupa o espaço restante */
}
Controles de Formulário
Grupos de entrada onde um rótulo, input e botão ficam em uma linha são perfeitos para Flexbox:
.input-group {
display: flex;
gap: 0.5rem;
}
.input-group input {
flex: 1; /* Input cresce para preencher o espaço */
}
.input-group button {
flex: 0 0 auto; /* Botão permanece no tamanho natural */
}