Grid: a grade de projetos e o bento
Uma dimensão, duas dimensões
Flexbox organiza numa fila: uma linha ou uma coluna. Grid organiza nas duas ao mesmo tempo.
Na prática você usa os dois: grid para a estrutura da página, flexbox para alinhar as coisas dentro de cada parte. No seu portfólio, a grade de projetos é grid; o miolo de cada cartão é flex.
Colunas
.grade {
display: grid;
grid-template-columns: 200px 1fr;
gap: var(--espaco-4);
}
Duas colunas: a primeira com 200px fixos, a segunda com todo o resto.
A unidade fr é fração do espaço livre:
grid-template-columns: 1fr 1fr 1fr; /* três iguais */
grid-template-columns: 1fr 2fr; /* a segunda com o dobro */
grid-template-columns: 200px 1fr 200px; /* laterais fixas, meio elástico */
repeat() encurta a repetição:
grid-template-columns: repeat(3, 1fr);
A grade de projetos, que se acomoda sozinha
.grade {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: var(--espaco-4);
list-style: none;
margin: 0;
padding: 0;
}
Leia assim: "quantas colunas couberem, cada uma com no mínimo 280px, dividindo o resto igualmente".
Numa tela de 1200px dá quatro colunas. Em 800px, duas. No celular, uma. Sem nenhuma media query: o navegador faz a conta.
O bento de "como trabalho"
Aquela grade de cartões de tamanhos diferentes, em que um ou dois se destacam, tem nome: bento, pela marmita japonesa de compartimentos desiguais. É a seção "Como trabalho" do seu portfólio.
.bento {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: var(--espaco-3);
list-style: none;
margin: 0;
padding: 0;
}
/* O primeiro cartão vale por dois */
.bento > li:first-child {
grid-column: span 2;
}
Uma linha de destaque, e a grade deixa de parecer uma tabela. Mas cuidado com
uma armadilha: numa tela onde só cabe uma coluna, span 2 pede duas colunas
que não existem. A correção é dizer ao navegador para não passar do que tem:
.bento > li:first-child {
grid-column: span 2;
}
@media (max-width: 560px) {
.bento > li:first-child {
grid-column: auto;
}
}
Áreas nomeadas
Para a estrutura de uma página inteira - por exemplo a portfolio.html, com uma
lateral de filtros:
.pagina {
display: grid;
grid-template-columns: 1fr 260px;
grid-template-areas:
"titulo titulo"
"projetos lateral";
gap: var(--espaco-5);
}
.pagina > h1 {
grid-area: titulo;
}
.pagina > .grade {
grid-area: projetos;
}
.pagina > aside {
grid-area: lateral;
}
O desenho em texto é o layout. Dá para ler a estrutura de relance, e rearranjá-la para o celular é reescrever o desenho:
@media (max-width: 768px) {
.pagina {
grid-template-columns: 1fr;
grid-template-areas:
"titulo"
"projetos"
"lateral";
}
}
Um item ocupando mais de uma célula
.destaque {
grid-column: span 2; /* duas colunas */
}
.faixa {
grid-column: 1 / -1; /* da primeira à última */
}
1 / -1 é o atalho para "a largura inteira da grade", e é o que se usa para um
título que atravessa a listagem de projetos.
Alinhar dentro da grade
.grade {
display: grid;
align-items: start; /* itens no topo da própria célula */
}
align-items: start é útil em listagem de cartões de alturas diferentes: sem
ele, todos esticam até a altura do maior.
No portfólio, quase sempre você quer o contrário - cartões da mesma altura, com os links alinhados embaixo. A próxima seção mostra como.
Grid e flexbox juntos: o cartão de projeto
/* Grid: a estrutura da listagem */
.grade {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: var(--espaco-4);
}
/* Flexbox: o miolo de cada cartão */
.cartao {
display: flex;
flex-direction: column;
gap: var(--espaco-2);
padding: var(--espaco-4);
border: 1px solid var(--borda);
border-radius: var(--raio);
background: var(--superficie);
}
/* A imagem sem deformar */
.cartao img {
width: 100%;
height: auto;
border-radius: calc(var(--raio) - 4px);
}
/* O link colado no rodapé do cartão, qualquer que seja o texto acima */
.cartao footer {
margin-top: auto;
padding-top: var(--espaco-3);
}
O margin-top: auto num item flex de coluna empurra o elemento para o fim; e é
o que alinha os links de "abrir projeto" de todos os cartões na mesma altura,
mesmo com descrições de tamanhos diferentes.
calc(var(--raio) - 4px) no arredondamento da imagem parece exagero e não é:
uma imagem com o mesmo raio do cartão que a contém deixa um fio de fundo visível
nos quatro cantos. O raio de dentro sempre é menor que o de fora, pela espessura
do recheio.
No portfólio
A portfolio.html fica pronta:
- a
.gradecomauto-fiteminmax(280px, 1fr)na página de projetos e na seção "Projetos selecionados" da inicial; - o
.bentode "Como trabalho", com um cartão em destaque e a correção dospan 2no celular; - cada
.cartaoem coluna flex, com a imagem emwidth: 100%e o rodapé preso embaixo pormargin-top: auto; - a
.gradetambém nos canais de contato e nos cargos da carreira.
Depois abra a portfolio.html e redimensione a janela do máximo ao mínimo. Os
cartões devem passar de quatro para três, dois e um sozinhos, sem nenhum salto
estranho e sem nenhuma media query - você ainda não escreveu a primeira.
Exercícios
- Monte a grade de projetos com
auto-fiteminmax. Redimensione a janela e conte as colunas em cada largura. - Monte o bento de "Como trabalho" com um cartão em destaque, e corrija o
span 2no celular. - Ponha
margin-top: autono rodapé dos cartões e compare com o resultado sem ele, usando descrições de tamanhos bem diferentes. - Faça o layout de
portfolio.htmlcom áreas nomeadas e reescreva o desenho para uma coluna só no celular. - Ponha um título atravessando a grade com
grid-column: 1 / -1. - Tire o
calc()do raio da imagem e olhe os cantos de perto. Você consegue ver o fio de fundo?
Referências
- Grid - MDN - o guia completo, em português
- A Complete Guide to Grid - CSS-Tricks - a referência visual
- Grid Garden - jogo para praticar, em português
Testa o que você leu
6 perguntas sobre esta aula. Errar aqui não custa nada - a explicação vem junto da correção.