Menu

CSS Grid: layout com colunas, linhas, fr, gap e áreas

O CSS grid organiza os itens em linhas e colunas ao mesmo tempo. Veja display: grid, grid-template-columns, a unidade fr, repeat() e minmax(), auto-fill vs auto-fit, como posicionar itens com grid-column e grid-template-areas, com um grid ao vivo que você edita e mede.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Um grid em três linhas

Defina display: grid em um contêiner e liste as colunas com grid-template-columns. Os filhos preenchem as células em ordem, da esquerda para a direita em português, e uma nova linha começa sempre que as colunas estão cheias:

Sete itens, três colunas: duas linhas completas e uma terceira linha com o item 7 na primeira coluna. Todas as colunas têm a mesma largura, e todos os itens de uma linha têm a mesma altura, então as bordas se alinham nas duas direções. É isso que o grid acrescenta em relação ao flexbox.

Playground de grid

Digite qualquer valor de grid-template-columns ou clique em um preset. O painel mostra as larguras de coluna que o navegador calculou (com getComputedStyle) e quantas linhas os itens precisaram:

Algumas coisas para observar: 1fr 2fr deixa a segunda coluna com exatamente o dobro da primeira. 200px 1fr mantém os 200px e dá o resto para a segunda coluna. auto 1fr auto dimensiona as colunas das pontas pelo conteúdo. repeat(4, 100px) deixa espaço vazio no fim, porque nada é flexível. Um valor inválido, como 1fr 2, é ignorado, e o grid mantém o último valor válido.

A unidade fr

fr significa "uma parte do espaço livre". O navegador primeiro tira as colunas fixas (px, rem, %, conteúdo auto) e os gaps, e depois divide o que sobra entre as colunas fr de acordo com os números delas.

grid-template-columns em um contêiner de 600px, sem gapLarguras das colunas
1fr 1fr 1fr200, 200, 200
1fr 2fr200, 400
100px 1fr 1fr100, 250, 250
1fr 50%300, 300

fr não é o mesmo que %: porcentagens mais gaps podem somar mais de 100% e transbordar, enquanto as colunas fr sempre dividem só o que sobra depois dos gaps.

repeat(), minmax() e um grid responsivo sem media queries

repeat(4, 1fr) é 1fr 1fr 1fr 1fr. minmax(120px, 1fr) é uma coluna que nunca fica mais estreita que 120px e cresce para pegar uma parte. Junte os dois com auto-fill ou auto-fit no lugar de uma quantidade, e o grid cria tantas colunas quantas couberem:

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px;
}

Essa única declaração dá tantas colunas de pelo menos 180px quantas o contêiner comporta: várias em uma tela larga, uma no celular, sem nenhuma media query. A diferença entre auto-fill e auto-fit aparece quando há menos itens que colunas:

O contêiner comporta cinco colunas de 100px. auto-fill mantém as cinco, então A, B e C ficam com 112px cada e sobram duas colunas vazias. auto-fit colapsa as vazias, então os três itens se esticam para uns 187px cada.

Posicionar itens: grid-column e grid-row

As linhas do grid são numeradas a partir de 1 na borda inicial. grid-column: 1 / 3 significa "da linha 1 até a linha 3", ou seja, duas colunas. span 2 significa "duas colunas a partir de onde você cair", e -1 é a última linha:

O item escuro ocupa a primeira linha inteira. O azul cobre um bloco de 2 por 2, e o âmbar duas linhas. Os itens a e b preenchem sozinhos as células que sobram: o grid coloca cada item que pode na próxima célula livre. grid-auto-rows: 60px define a altura das linhas que você não declarou com grid-template-rows.

grid-template-areas: dê nome às partes de um layout

Para um layout de página, dê nome às áreas e desenhe-as como texto. Cada string é uma linha, cada palavra uma célula, e um item entra em uma área com grid-area:

O cabeçalho e o rodapé ocupam as duas colunas porque os nomes deles preenchem as duas células das respectivas linhas. A linha do meio é 1fr, então pega a altura que sobrar dos 280px. Para empilhar tudo no celular, uma media query só precisa redesenhar as áreas como uma coluna: grid-template-areas: "header" "side" "main" "footer" com grid-template-columns: 1fr. A página de media queries mostra o padrão.

Alinhar dentro das células

Por padrão, os itens do grid se esticam para preencher a célula. Estas propriedades os movem dentro dela:

PropriedadeEmMove
justify-itemscontêinertodos os itens ao longo da linha (eixo inline)
align-itemscontêinertodos os itens para cima e para baixo (eixo de bloco)
place-itemscontêinershorthand: place-items: center centraliza nos dois
justify-self / align-selfitemum item
justify-content / align-contentcontêinero conjunto inteiro de trilhas, quando o grid é menor que o contêiner

display: grid; place-items: center; é o jeito mais curto de centralizar um filho em uma caixa.

Grid ou flexbox

O grid é bidimensional: você decide as colunas (e as linhas), e o conteúdo as preenche, então todos os cards de uma galeria têm a mesma largura, até na última linha. O flexbox é unidimensional: os itens se dimensionam pelo conteúdo ao longo de uma única linha. Os dois combinam bem: um grid para a página e para a galeria de cards, flexbox dentro de cada card para a linha do cabeçalho. A página do flexbox cobre a outra metade.

Ordem e acessibilidade

grid-template-areas, grid-row, grid-column e order podem colocar um item em qualquer lugar, mas os leitores de tela e a tecla Tab continuam seguindo a ordem do HTML. Mantenha a ordem do código com sentido (cabeçalho, navegação, conteúdo principal, rodapé) e use o grid para arrumá-la, não para consertar uma ordem de HTML que não faz sentido.

Erros comuns

  • Colocar display: grid nos itens. Ele vai no pai; só os filhos diretos são itens do grid.
  • Usar porcentagens com gaps. grid-template-columns: 50% 50% mais gap: 16px transborda 16px. Use 1fr 1fr.
  • auto-fill quando você queria auto-fit. Com poucos itens, auto-fill deixa colunas vazias. Troque para auto-fit para esticar os itens.
  • Uma coluna 1fr que cresce além da parte dela. Uma coluna 1fr não encolhe abaixo do conteúdo mais longo (uma URL longa, uma imagem larga). Use minmax(0, 1fr) para deixá-la encolher.
  • Strings de área que não formam retângulos. Toda área nomeada precisa formar um retângulo, e todas as strings de linha precisam ter o mesmo número de células, senão a declaração grid-template-areas inteira é ignorada.
  • Esquecer que a numeração das linhas começa em 1. Três colunas têm quatro linhas: 1 / 4 ou 1 / -1 ocupa as três.

Perguntas frequentes

O que é CSS grid?

Um sistema de layout que posiciona elementos em linhas e colunas ao mesmo tempo. Você define display: grid em um contêiner, descreve as colunas com grid-template-columns (e, se quiser, as linhas), e os filhos diretos preenchem as células em ordem.

O que significa 1fr no CSS grid?

fr é uma fração do espaço livre no contêiner grid. grid-template-columns: 1fr 1fr 1fr dá três colunas iguais, e 1fr 2fr deixa a segunda coluna com o dobro da largura da primeira. Tamanhos fixos e gaps saem primeiro; as colunas fr dividem o que sobra.

Qual a diferença entre auto-fill e auto-fit?

Os dois criam tantas colunas quantas couberem. auto-fill mantém as colunas vazias, então poucos itens continuam estreitos e deixam espaço vazio no fim da linha. auto-fit colapsa as colunas vazias, então os itens se esticam para preencher a linha. Com itens suficientes para encher a linha, os dois ficam iguais.

Como fazer um item do grid ocupar duas colunas?

Use grid-column: span 2 no item, ou dê a ele linhas de início e fim: grid-column: 1 / 3 cobre as colunas 1 e 2. grid-column: 1 / -1 ocupa a largura toda, porque -1 é a última linha.

Quando usar grid em vez de flexbox?

Use grid quando linhas e colunas precisam se alinhar entre si: galerias de cards, formulários com rótulos alinhados, uma página com cabeçalho, barra lateral e rodapé. Use flexbox para uma única linha ou coluna cujos itens se dimensionam pelo conteúdo, como uma barra de navegação.

grid-gap é o mesmo que gap?

Sim. grid-gap, grid-row-gap e grid-column-gap são os nomes antigos. Os navegadores ainda os aceitam como apelidos, mas escreva gap, row-gap e column-gap, que também funcionam no flexbox.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR