Pular para o conteúdo
murad.guide

A Web Aberta

Capítulo 28

CSS Grid

4 min de leitura 724 palavras 3 gravuras

Esta é o capítulo 28 de 52 do volume Aprenda a Web. O projeto-fio é a Oficina Costeira, um coletivo fictício de design em João Pessoa. Nada aqui é cadastro real. O exemplo está em exemplos/28-css-grid/. Em cada capítulo: leia, copie, mude uma coisa, preveja, recarregue e confira.

O que você vai aprender

Grade em duas dimensões

Flexbox alinha em um eixo. Grid trabalha colunas e linhas ao mesmo tempo. Os filhos diretos viram itens da grade. Netos não entram, a menos que o filho também seja uma grade.

Termos estáveis:

<!DOCTYPE html>
<html lang="pt-BR">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Projetos — Oficina Costeira</title>
    <link rel="stylesheet" href="assets/stylesheets/main.css">
  </head>
  <body>
    <dl class="projetos">
      <div>
        <dt>Identidade da orla</dt>
        <dd>Marca fictícia para um ateliê na Praia do Jacaré.</dd>
      </div>
      <div>
        <dt>Cartaz da oficina</dt>
        <dd>Folha A3 com tipografia grande e pouca cor.</dd>
      </div>
      <div>
        <dt>Site estático</dt>
        <dd>Páginas que abrem no navegador, sem conta paga.</dd>
      </div>
    </dl>
  </body>
</html>
.projetos {
  display: grid;
}

Sem colunas declaradas, o navegador cria uma coluna e três linhas. Leia o HTML. Copie. Mude display para block. Preveja a pilha. Recarregue.

Colunas, frações e vãos

grid-template-columns descreve a largura de cada coluna. 1fr é uma fração do espaço livre.

.projetos {
  display: grid;
  grid-template-columns: 3fr 1fr;
  gap: 1rem;
}

Três cartões em duas colunas: o terceiro desce para a linha seguinte. gap é o vão entre itens, não a margem de fora. Dá para separar column-gap e row-gap.

repeat(3, 1fr) escreve três colunas iguais sem copiar 1fr três vezes.

Erro comum: colocar gap e ainda margin grande em cada cartão. O vão duplica. Comece pelo gap.

Mude 3fr 1fr para 1fr 1fr 1fr. Preveja três colunas. Recarregue.

Linhas numeradas

As linhas da grade têm número. A primeira vertical é 1. A última pode ser -1, sem contar quantas existem.

.projetos {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
}

.projetos > div:nth-child(1) {
  grid-column: 1 / 3;
}

.projetos > div:nth-child(2) {
  grid-column: 4 / -1;
}

grid-column: 1 / 3 começa na linha 1 e termina na 3: ocupa duas colunas. grid-row faz o mesmo no eixo vertical.

A ordem do HTML continua a ordem da leitura e do teclado. Mover visualmente não reordena o leitor de tela.

Resumo dos conceitos: grid-template, gap, área

Áreas com nome

grid-template-areas desenha o mapa com palavras. Cada string é uma linha. Nomes iguais colados esticam a área.

.pagina {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
  grid-template-areas:
    "cabeca"
    "principal"
    "lateral"
    "rodape";
}

header { grid-area: cabeca; }
main { grid-area: principal; }
aside { grid-area: lateral; }
footer { grid-area: rodape; }

Na tela larga, redesenhe o mapa. O HTML não muda.

@media (min-width: 48rem) {
  .pagina {
    grid-template-columns: 12rem 1fr;
    grid-template-areas:
      "cabeca cabeca"
      "lateral principal"
      "rodape rodape";
  }
}

O exemplo 28-css-grid usa esse recorte: uma coluna no telefone, barra e conteúdo a partir de 48rem.

Mapa de áreas da página: cabeçalho, lateral, principal e rodapé

Erro comum: escrever "cabeca cabeca" numa linha e "cabeca" na outra, com número diferente de colunas. A grade quebra. Conte as células de cada string.

Sobrepor no mesmo trilho

Título sobre foto: os dois ocupam as mesmas linhas. z-index decide quem fica na frente.

.banner {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: auto 4em;
}

.banner img {
  grid-column: 1 / -1;
  grid-row: 1 / -1;
}

.banner h2 {
  grid-column: 1 / -1;
  grid-row: 2;
  z-index: 1;
  margin: 0;
}

Se o h2 vem antes da img no HTML, a imagem cobre o texto. Suba o z-index do título. Não use position: absolute se a grade já resolve.

Copie. Troque grid-row do h2 para 1. Preveja o título no topo. Recarregue.

Grade que se ajeita sozinha

repeat(auto-fit, minmax(15rem, 1fr)) cria quantas colunas couberem. Cada coluna tem no mínimo 15rem e no máximo uma fração.

.projetos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  gap: 1rem;
}

min(15rem, 100%) evita corte na tela estreita: se 15rem não cabe, a coluna usa 100%.

Alinhe itens com as mesmas propriedades do Flexbox: justify-items, align-items, place-items. align-self ajusta um cartão só.

Resumo dos conceitos: área, gap, grid-template

Atividades

  1. Qual unidade divide o espaço livre da grade em partes iguais?
  2. O que grid-column: 1 / -1 faz com um item?
  3. Por que repetir o nome cabeca duas vezes na mesma string de grid-template-areas?
  4. A imagem cobre o h2 no banner. Qual propriedade sobe o título?
  5. Escreva uma grid-template-columns que crie colunas flexíveis de no mínimo 15rem.

Respostas comentadas

  1. fr. 1fr 1fr são duas metades do espaço livre, depois de larguras fixas e gap.
  2. O item começa na primeira linha e termina na última: atravessa todas as colunas.
  3. A área cabeca ocupa duas colunas naquela fileira. Sem repetir, o mapa ficaria inconsistente.
  4. z-index no h2, com a imagem e o título na mesma célula.
  5. repeat(auto-fit, minmax(min(15rem, 100%), 1fr)).

Referências

O arquivo completo

Referência do exemplo 28-css-grid, reproduzida aqui para que você possa conferir sem sair da página.

assets/javascript/simulacao.js

const form=document.querySelector("#simulacao");if(form){form.querySelector("button[type=submit]").disabled=false;form.addEventListener("submit",event=>{event.preventDefault();document.querySelector("#retorno").textContent="Simulação concluída. Nada foi enviado ou guardado.";});}