Guia definitivo para dominar Flexbox e Grid no CSS
Domine layouts modernos: Flexbox para componentes, Grid para páginas, exemplos práticos, truques e quando usar cada um.
Introdução: Por que Flexbox e Grid mudaram tudo
Antes de Flexbox e Grid, criávamos layouts com floats, tabelas e hacks de display: inline-block. Hoje, temos duas ferramentas poderosas e complementares que resolvem praticamente qualquer desafio de layout.
Quando usar cada um
- Flexbox: layouts unidimensionais (linha ou coluna). Ideal para navbars, cards, botões alinhados, componentes.
- Grid: layouts bidimensionais (linhas e colunas simultâneas). Ideal para páginas completas, galerias, dashboards.
Flexbox: Dominando layouts em uma dimensão
Conceitos básicos
Flexbox trabalha com um container (elemento pai) e items (filhos). Ao definir display: flex no container, os filhos se tornam flex items.
Propriedades do container
1. display: flex
.container {
display: flex; /* ou inline-flex */
}
2. flex-direction (direção do eixo principal)
.container {
display: flex;
flex-direction: row; /* padrão: horizontal */
/* flex-direction: row-reverse; da direita para a esquerda */
/* flex-direction: column; vertical */
/* flex-direction: column-reverse; */
}
3. justify-content (alinhamento no eixo principal)
.container {
display: flex;
justify-content: flex-start; /* padrão */
/* justify-content: center; centralizado */
/* justify-content: flex-end; fim */
/* justify-content: space-between; espaçamento entre */
/* justify-content: space-around; espaçamento ao redor */
/* justify-content: space-evenly; espaçamento uniforme */
}
4. align-items (alinhamento no eixo transversal)
.container {
display: flex;
align-items: stretch; /* padrão: estica */
/* align-items: flex-start; topo */
/* align-items: center; centro */
/* align-items: flex-end; fim */
/* align-items: baseline; linha base do texto */
}
5. flex-wrap (quebra de linha)
.container {
display: flex;
flex-wrap: nowrap; /* padrão: não quebra */
/* flex-wrap: wrap; quebra para próxima linha */
/* flex-wrap: wrap-reverse; quebra invertida */
}
6. gap (espaçamento entre items)
.container {
display: flex;
gap: 16px; /* espaçamento uniforme */
/* gap: 16px 24px; linha coluna */
}
Propriedades dos flex items
1. flex-grow (proporção de crescimento)
.item {
flex-grow: 1; /* cresce proporcionalmente */
}
/* Exemplo: 3 itens, sendo um maior */
.item1 { flex-grow: 1; }
.item2 { flex-grow: 2; } /* 2x maior */
.item3 { flex-grow: 1; }
2. flex-shrink (proporção de encolhimento)
.item {
flex-shrink: 1; /* padrão: pode encolher */
/* flex-shrink: 0; não encolhe */
}
3. flex-basis (tamanho base)
.item {
flex-basis: 200px; /* tamanho inicial antes de crescer/encolher */
/* flex-basis: auto; usa width/height */
}
4. flex (shorthand)
.item {
flex: 1; /* equivale a: flex-grow: 1; flex-shrink: 1; flex-basis: 0; */
/* flex: 0 0 200px; não cresce, não encolhe, tamanho fixo 200px */
}
5. align-self (alinhamento individual)
.item {
align-self: center; /* sobrescreve align-items do container */
}
Exemplos práticos com Flexbox
Exemplo 1: Navbar responsiva
<nav class="navbar">
<div class="logo">Logo</div>
<ul class="menu">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background: #333;
color: white;
}
.menu {
display: flex;
gap: 2rem;
list-style: none;
}
@media (max-width: 768px) {
.navbar {
flex-direction: column;
gap: 1rem;
}
}
Exemplo 2: Cards com tamanhos flexíveis
<div class="cards">
<div class="card">Card 1</div>
<div class="card">Card 2</div>
<div class="card">Card 3</div>
</div>
.cards {
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
.card {
flex: 1 1 300px; /* cresce, encolhe, base 300px */
padding: 2rem;
background: #f0f0f0;
border-radius: 8px;
}
Exemplo 3: Centralização perfeita
<div class="center">
<div class="content">Centralizado vertical e horizontalmente</div>
</div>
.center {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.content {
padding: 2rem;
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
CSS Grid: Dominando layouts bidimensionais
Conceitos básicos
Grid divide o espaço em linhas e colunas, criando células onde os itens são posicionados.
Propriedades do container
1. display: grid
.container {
display: grid;
}
2. grid-template-columns (definir colunas)
.container {
display: grid;
grid-template-columns: 200px 200px 200px; /* 3 colunas de 200px */
/* grid-template-columns: 1fr 1fr 1fr; 3 colunas iguais */
/* grid-template-columns: 1fr 2fr 1fr; coluna do meio 2x maior */
/* grid-template-columns: repeat(3, 1fr); atalho para 3 colunas iguais */
/* grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); responsivo */
}
3. grid-template-rows (definir linhas)
.container {
display: grid;
grid-template-rows: 100px 200px 100px;
/* grid-template-rows: auto auto auto; altura automática */
}
4. gap (espaçamento)
.container {
display: grid;
gap: 20px; /* espaçamento uniforme */
/* gap: 20px 40px; linha coluna */
/* column-gap: 40px; apenas colunas */
/* row-gap: 20px; apenas linhas */
}
5. grid-template-areas (layout semântico)
.container {
display: grid;
grid-template-columns: 1fr 3fr 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"sidebar content aside"
"footer footer footer";
gap: 1rem;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
Propriedades dos grid items
1. grid-column e grid-row (posicionamento)
.item {
grid-column: 1 / 3; /* da coluna 1 até 3 (ocupa 2 colunas) */
grid-row: 1 / 2; /* da linha 1 até 2 */
/* grid-column: span 2; ocupa 2 colunas a partir da posição */
}
2. justify-self e align-self
.item {
justify-self: center; /* alinha horizontalmente na célula */
align-self: center; /* alinha verticalmente na célula */
}
Exemplos práticos com Grid
Exemplo 1: Layout de página completo
<div class="page">
<header>Header</header>
<nav>Navigation</nav>
<main>Main Content</main>
<aside>Sidebar</aside>
<footer>Footer</footer>
</div>
.page {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
gap: 1rem;
min-height: 100vh;
}
header { grid-area: header; background: #333; color: white; padding: 1rem; }
nav { grid-area: nav; background: #f0f0f0; padding: 1rem; }
main { grid-area: main; padding: 1rem; }
aside { grid-area: aside; background: #f0f0f0; padding: 1rem; }
footer { grid-area: footer; background: #333; color: white; padding: 1rem; }
@media (max-width: 768px) {
.page {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
}
}
Exemplo 2: Galeria de imagens responsiva
<div class="gallery">
<img src="1.jpg" alt="Image 1">
<img src="2.jpg" alt="Image 2">
<img src="3.jpg" alt="Image 3">
<img src="4.jpg" alt="Image 4">
<img src="5.jpg" alt="Image 5">
<img src="6.jpg" alt="Image 6">
</div>
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
.gallery img {
width: 100%;
height: 250px;
object-fit: cover;
border-radius: 8px;
}
Exemplo 3: Dashboard com áreas de tamanhos diferentes
<div class="dashboard">
<div class="widget widget-large">Gráfico Principal</div>
<div class="widget">Estatística 1</div>
<div class="widget">Estatística 2</div>
<div class="widget widget-wide">Tabela</div>
</div>
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1rem;
}
.widget {
background: white;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.widget-large {
grid-column: span 2;
grid-row: span 2;
}
.widget-wide {
grid-column: span 4;
}
Combinando Flexbox e Grid
Muitas vezes, a melhor solução é combinar as duas técnicas.
Exemplo: Grid para layout, Flexbox para componentes
<div class="page-grid">
<header class="header-flex">
<div class="logo">Logo</div>
<nav class="nav-flex">
<a href="#">Home</a>
<a href="#">About</a>
<a href="#">Contact</a>
</nav>
</header>
<main>Content</main>
<footer>Footer</footer>
</div>
.page-grid {
display: grid;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.header-flex {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background: #333;
color: white;
}
.nav-flex {
display: flex;
gap: 2rem;
}
.nav-flex a {
color: white;
text-decoration: none;
}
Truques e dicas avançadas
1. Auto-fit vs auto-fill no Grid
/* auto-fit: colunas se expandem para preencher espaço */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
/* auto-fill: colunas mantêm tamanho mínimo, criando espaços vazios */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
2. Ordem visual diferente da ordem no HTML
.item1 { order: 3; } /* aparece por último */
.item2 { order: 1; } /* aparece primeiro */
.item3 { order: 2; } /* aparece no meio */
3. Sticky footer com Flexbox
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1; /* ocupa todo espaço disponível */
}
footer {
/* sempre fica no final */
}
4. Grid com linhas nomeadas
.container {
display: grid;
grid-template-columns: [inicio] 1fr [meio] 1fr [fim];
}
.item {
grid-column: inicio / meio;
}
Compatibilidade e fallbacks
Flexbox e Grid têm suporte em todos os navegadores modernos (98%+). Para navegadores antigos (IE11), use feature queries:
/* Fallback para navegadores antigos */
.container {
display: block;
}
/* Grid para navegadores modernos */
@supports (display: grid) {
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
}
Ferramentas úteis
- Firefox DevTools: melhor inspetor de Grid e Flexbox.
- CSS Grid Generator: cssgrid-generator.netlify.app
- Flexbox Froggy: jogo para aprender Flexbox (flexboxfroggy.com)
- Grid Garden: jogo para aprender Grid (cssgridgarden.com)
Conclusão
Flexbox e Grid não são concorrentes, são complementares. Use Flexbox para componentes e layouts unidimensionais. Use Grid para layouts de página e estruturas bidimensionais. Combine os dois para criar interfaces modernas, responsivas e fáceis de manter.
FAQ
Devo usar Grid ou Flexbox?
Depende. Flexbox para uma dimensão (linha ou coluna), Grid para duas dimensões (linhas e colunas). Muitas vezes você usará os dois juntos.
Grid substitui Flexbox?
Não. Flexbox ainda é melhor para componentes pequenos e alinhamento dinâmico. Grid é melhor para estruturas de página.
Como fazer um layout responsivo?
Use repeat(auto-fit, minmax(250px, 1fr)) no Grid ou flex-wrap: wrap no Flexbox, combinados com media queries.
O que é fr no Grid?
fr (fraction) distribui o espaço disponível proporcionalmente. 1fr 2fr significa que a segunda coluna será o dobro da primeira.
Posso usar Grid dentro de Flexbox?
Sim! É muito comum. Por exemplo, usar Grid para o layout da página e Flexbox para a navbar dentro do header.