Exemplos práticos de layouts com CSS Grid
Construa layouts de página inteira, dashboards e galerias de imagens usando CSS Grid.
Até agora, você explorou as propriedades individuais do CSS Grid. Agora é a hora de combinar todo esse conhecimento para construir layouts completos e responsivos, que são a razão de ser do Grid.
Vamos criar alguns layouts comuns que você encontrará em quase todo site, usando o CSS Grid de forma eficiente.
Exemplo 1: Layout de Página Clássico (Cabeçalho, Sidebar, Conteúdo, Rodapé)
Este é um dos layouts mais fundamentais na web. Com CSS Grid e grid-template-areas, ele se torna incrivelmente fácil de criar e manter.
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Layout de Página Clássico com Grid</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
min-height: 100vh; /* Garante que o body ocupe a altura total da viewport */
display: grid; /* Transforma o body em um contêiner grid */
grid-template-columns: 1fr; /* Por padrão, uma única coluna */
grid-template-rows: auto 1fr auto; /* Cabeçalho auto, conteúdo flexível, rodapé auto */
grid-template-areas:
"header"
"main"
"footer";
}
.header, .sidebar, .main-content, .footer {
padding: 20px;
border: 1px solid #ccc;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
color: white;
}
.header {
background-color: #333;
grid-area: header;
}
.sidebar {
background-color: #555;
grid-area: sidebar; /* Nomeamos, mas ainda não usamos no layout padrão */
}
.main-content {
background-color: #777;
grid-area: main;
}
.footer {
background-color: #333;
grid-area: footer;
}
/* Layout para telas maiores (desktop) */
@media (min-width: 768px) {
body {
grid-template-columns: 200px 1fr; /* Sidebar de 200px, conteúdo flexível */
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
}
</style>
</head>
<body>
<header class="header">Cabeçalho</header>
<aside class="sidebar">Barra Lateral</aside>
<main class="main-content">Conteúdo Principal</main>
<footer class="footer">Rodapé</footer>
</body>
</html>
Análise:
- O
bodyé o Contêiner Grid, ocupando 100% da altura da viewport (min-height: 100vh;). - Mobile-first: Por padrão (telas pequenas), o layout é de uma única coluna, com os elementos empilhados.
@media (min-width: 768px): Para telas maiores, redefinimosgrid-template-columnspara ter uma barra lateral e o conteúdo, egrid-template-areaspara posicionar os elementos de forma diferente.grid-template-rows: auto 1fr auto;garante que o cabeçalho e rodapé tenham altura automática e o conteúdo principal ocupe todo o espaço vertical restante.
Exemplo 2: Galeria de Imagens Responsiva
Uma galeria de imagens que se adapta ao número de colunas conforme o tamanho da tela, usando repeat() com auto-fit e minmax().
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Galeria de Imagens com Grid</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f4f4f4;
}
.gallery-container {
display: grid;
/* Colunas que se ajustam: mínimo de 250px, máximo de 1fr */
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px;
padding: 15px;
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.gallery-item {
background-color: #e0e0e0;
border: 1px solid #ccc;
border-radius: 4px;
overflow: hidden; /* Garante que a imagem não transborde */
text-align: center;
}
.gallery-item img {
width: 100%;
height: 200px; /* Altura fixa para as imagens */
object-fit: cover; /* Garante que a imagem cubra a área sem distorcer */
display: block; /* Remove espaço extra abaixo da imagem */
}
.gallery-item p {
padding: 10px;
margin: 0;
color: #333;
font-size: 0.9em;
}
</style>
</head>
<body>
<h1>Minha Galeria de Fotos</h1>
<div class="gallery-container">
<div class="gallery-item">
<img src="https://via.placeholder.com/400x200/FF5733/FFFFFF?text=Foto+1" alt="Foto 1">
<p>Descrição da Foto 1</p>
</div>
<div class="gallery-item">
<img src="https://via.placeholder.com/400x200/33FF57/FFFFFF?text=Foto+2" alt="Foto 2">
<p>Descrição da Foto 2</p>
</div>
<div class="gallery-item">
<img src="https://via.placeholder.com/400x200/3357FF/FFFFFF?text=Foto+3" alt="Foto 3">
<p>Descrição da Foto 3</p>
</div>
<div class="gallery-item">
<img src="https://via.placeholder.com/400x200/FF33FF/FFFFFF?text=Foto+4" alt="Foto 4">
<p>Descrição da Foto 4</p>
</div>
<div class="gallery-item">
<img src="https://via.placeholder.com/400x200/FFFF33/000000?text=Foto+5" alt="Foto 5">
<p>Descrição da Foto 5</p>
</div>
<div class="gallery-item">
<img src="https://via.placeholder.com/400x200/33FFFF/FFFFFF?text=Foto+6" alt="Foto 6">
<p>Descrição da Foto 6</p>
</div>
<div class="gallery-item">
<img src="https://via.placeholder.com/400x200/FF3333/FFFFFF?text=Foto+7" alt="Foto 7">
<p>Descrição da Foto 7</p>
</div>
<div class="gallery-item">
<img src="https://via.placeholder.com/400x200/33FF33/FFFFFF?text=Foto+8" alt="Foto 8">
<p>Descrição da Foto 8</p>
</div>
</div>
</body>
</html>
Análise:
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));é a chave aqui. Ele diz: "Crie o máximo de colunas que couberem, onde cada coluna tem no mínimo 250px e no máximo 1 fração do espaço disponível."gap: 15px;mantém um espaçamento consistente entre as imagens.- Redimensione a janela do navegador para ver como o número de colunas se ajusta automaticamente.
Exemplo 3: Dashboard com Widgets de Tamanhos Variados
Um layout de dashboard onde alguns widgets ocupam mais espaço que outros, usando grid-column e grid-row para posicionamento explícito.
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Dashboard com Grid</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f4f4f4;
}
.dashboard-container {
display: grid;
grid-template-columns: repeat(4, 1fr); /* 4 colunas de largura igual */
grid-template-rows: repeat(3, 150px); /* 3 linhas de 150px de altura */
gap: 20px;
padding: 20px;
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
max-width: 1200px;
margin: 0 auto;
}
.widget {
background-color: #add8e6; /* Light Blue */
border: 1px solid #87ceeb; /* Sky Blue */
border-radius: 8px;
padding: 15px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-weight: bold;
color: #333;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
/* Widgets de tamanhos variados */
.widget-large {
grid-column: span 2; /* Ocupa 2 colunas */
grid-row: span 2; /* Ocupa 2 linhas */
background-color: #90ee90; /* Light Green */
border-color: #32cd32; /* Lime Green */
}
.widget-wide {
grid-column: span 3; /* Ocupa 3 colunas */
background-color: #ffb6c1; /* Light Pink */
border-color: #ff69b4; /* Hot Pink */
}
.widget-tall {
grid-row: span 2; /* Ocupa 2 linhas */
background-color: #ffd700; /* Gold */
border-color: #daa520; /* Goldenrod */
}
</style>
</head>
<body>
<h1>Meu Dashboard</h1>
<div class="dashboard-container">
<div class="widget widget-large">Widget Grande (2x2)</div>
<div class="widget">Widget Pequeno</div>
<div class="widget">Widget Pequeno</div>
<div class="widget-wide">Widget Largo (1x3)</div>
<div class="widget">Widget Pequeno</div>
<div class="widget-tall">Widget Alto (2x1)</div>
<div class="widget">Widget Pequeno</div>
<div class="widget">Widget Pequeno</div>
</div>
</body>
</html>
Análise:
- Definimos um grid base de 4 colunas e 3 linhas.
- Usamos
grid-column: span X;egrid-row: span Y;nos widgets para fazê-los ocupar múltiplas células. - O Grid se encarrega de organizar os widgets restantes nos espaços vazios.
Exemplo 4: Layout de Blog com Destaque
Um layout de blog onde o primeiro post é um destaque que ocupa mais espaço, e os outros posts se organizam em um grid.
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Layout de Blog com Grid</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f4f4f4;
}
.blog-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); /* Colunas flexíveis */
grid-auto-rows: minmax(250px, auto); /* Altura mínima para as linhas */
gap: 20px;
padding: 20px;
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
max-width: 1200px;
margin: 0 auto;
}
.blog-post {
background-color: #f0f8ff; /* Alice Blue */
border: 1px solid #b0e0e6; /* Powder Blue */
border-radius: 8px;
padding: 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.blog-post h3 {
margin-top: 0;
color: #333;
}
.blog-post p {
color: #666;
flex-grow: 1; /* Faz o parágrafo ocupar o espaço restante */
}
.blog-post a {
display: inline-block;
background-color: #007bff;
color: white;
padding: 8px 15px;
border-radius: 5px;
text-decoration: none;
align-self: flex-start; /* Alinha o botão à esquerda */
}
/* Post de destaque */
.featured-post {
grid-column: 1 / -1; /* Ocupa todas as colunas */
grid-row: span 2; /* Ocupa 2 linhas */
background-color: #ffe4e1; /* Misty Rose */
border-color: #ff6347; /* Tomato */
display: grid; /* Transforma o post de destaque em um grid interno */
grid-template-columns: 1fr 2fr; /* Imagem e conteúdo */
gap: 20px;
align-items: center;
}
.featured-post img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 5px;
}
.featured-post .content {
display: flex;
flex-direction: column;
justify-content: center;
}
/* Responsividade para o post de destaque */
@media (max-width: 768px) {
.featured-post {
grid-template-columns: 1fr; /* Em telas menores, imagem e texto empilham */
grid-row: auto; /* Não ocupa 2 linhas, apenas o necessário */
}
.featured-post img {
height: 200px; /* Altura fixa para a imagem em mobile */
}
}
</style>
</head>
<body>
<h1>Últimas do Blog</h1>
<div class="blog-container">
<div class="blog-post featured-post">
<img src="https://via.placeholder.com/600x400/8A2BE2/FFFFFF?text=Post+Destaque" alt="Post Destaque">
<div class="content">
<h3>Título do Post de Destaque</h3>
<p>Este é o nosso post mais importante, ocupando um espaço privilegiado no layout. Ele é responsivo e se adapta a diferentes tamanhos de tela.</p>
<a href="#">Leia Mais</a>
</div>
</div>
<div class="blog-post">
<h3>Post Comum 1</h3>
<p>Um artigo interessante sobre as novidades do desenvolvimento web.</p>
<a href="#">Leia Mais</a>
</div>
<div class="blog-post">
<h3>Post Comum 2</h3>
<p>Dicas e truques para otimizar seu código CSS.</p>
<a href="#">Leia Mais</a>
</div>
<div class="blog-post">
<h3>Post Comum 3</h3>
<p>Entrevista com um desenvolvedor front-end experiente.</p>
<a href="#">Leia Mais</a>
</div>
<div class="blog-post">
<h3>Post Comum 4</h3>
<p>Como criar componentes reutilizáveis com JavaScript.</p>
<a href="#">Leia Mais</a>
</div>
</div>
</body>
</html>
Análise:
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));cria um grid de posts flexível.grid-auto-rows: minmax(250px, auto);garante que as linhas tenham uma altura mínima, mas se ajustem ao conteúdo..featured-postusagrid-column: 1 / -1;para ocupar todas as colunas egrid-row: span 2;para ocupar duas linhas.- O post de destaque é, por si só, um Contêiner Grid (
display: grid;) com duas colunas (1fr 2fr), demonstrando como você pode aninhar grids. - Media query para o post de destaque: em telas menores, ele volta a ser uma única coluna, com a imagem e o texto empilhados.
Conclusão
Estes exemplos demonstram a versatilidade e o poder do CSS Grid. Com ele, você pode criar desde layouts de página inteira complexos até componentes responsivos, com um código muito mais limpo e fácil de manter do que com métodos antigos. A chave é entender as propriedades do Contêiner Grid e dos Itens Grid, e como elas interagem para construir a estrutura desejada.