Iniciando com o CSS Grid: o guia básico sobre o display grid.

O display grid é o recurso do CSS que permite montar layouts em linhas e colunas com controle total sobre a posição de cada elemento na página. Neste guia básico, você vai entender os conceitos que formam o pontapé inicial para usar o CSS Grid com segurança.

Das tabelas ao display grid

Se voltarmos alguns anos no passado, criar layouts significava usar tabelas, com a famosa tag <table>. Até existiam recursos externos, como o Bootstrap, mas eles não eram tão óbvios quanto o uso da tabela.

Com isso, surgiu a necessidade de algo mais prático para construir páginas. Além disso, os desenvolvedores queriam controle total sobre a posição de qualquer elemento.

Se analisarmos a tabela, temos linhas e colunas. Ou seja, ela oferece controle sobre onde colocar cada elemento, indicando em qual linha e coluna ele deve ficar.

O display grid veio para facilitar esse desenvolvimento. Ele é muito mais prático do que as tabelas, porém mantém o mesmo controle sobre a posição de cada elemento.

Na prática, o CSS Grid é um sistema de layout bidimensional. Por isso, ele organiza o conteúdo nos dois eixos ao mesmo tempo, enquanto o Flexbox trabalha melhor em uma única direção.

O container no display grid

Se você já usou Flexbox, o conceito de container no Grid vai parecer familiar. Caso ainda não conheça, o artigo entendendo o Flexbox e como começar do jeito certo é um bom complemento.

Basicamente, o container é um wrapper que envolve todos os elementos do layout. Em outras palavras, ele funciona como um componente pai que agrupa todos os filhos.

Esse container também define o tipo de display que vamos usar, que neste caso é o display grid:

.grid-container {
    display: grid;
}

Um detalhe importante: apenas os filhos diretos do container viram itens do grid. Segundo a documentação de conceitos básicos do CSS Grid no MDN, os netos continuam com o fluxo normal, a menos que o filho também vire um container.

Logo, se você precisar posicionar um elemento mais interno, aplique o display grid também no elemento pai dele. Assim, você cria grids aninhados de forma controlada.

Colunas, linhas e gaps no display grid

Como vimos, o Grid é a evolução dos layouts criados com tabelas. Porém, ele mantém o conceito de tabela, então todo layout com display grid se baseia em linhas e colunas.

Assim como nas tabelas, você pode colocar um espaçamento entre cada célula. Isto é, um espaçamento entre cada linha e coluna para organizar ainda mais o conteúdo.

Esse espaçamento entre linhas e colunas recebe o nome de gap. Em seguida, vamos ver as três peças que formam essa estrutura.

Definindo colunas com grid-template-columns

O ponto mais interessante de trabalhar com display grid é usar linhas e colunas ao mesmo tempo. Para isso, ele oferece duas propriedades que controlam cada linha e cada coluna de forma independente.

A propriedade grid-template-columns define quantas colunas o grid terá. Cada valor colocado nela vira uma nova coluna.

.grid-container {
    display: grid;
    grid-template-columns: 100px 250px;
    grid-column-gap: 20px;
}

No exemplo acima, configuramos o grid com duas colunas diferentes. A primeira terá 100px de largura, e a segunda, 250px.

Também definimos um gap de 20px, ou seja, o espaçamento entre cada coluna.

Definindo linhas com grid-template-rows

Agora que definimos as colunas, podemos definir quantas linhas o grid terá. Para isso, usamos a propriedade grid-template-rows.

Ela funciona como a grid-template-columns. Assim, cada valor informado vira uma nova linha.

.grid-container {
    display: grid;
    grid-template-columns: 100px 250px;
    grid-template-rows: 50px 70px;
    grid-column-gap: 20px;
    grid-row-gap: 10px;
}

Dessa forma, o grid passa a ter duas linhas, a primeira com 50px de altura e a segunda com 70px. Além disso, o gap entre as linhas fica em 10px.

Com isso, montamos uma estrutura com duas linhas e duas colunas. Também definimos um valor de gap para as linhas e outro para as colunas.

Simplificando o espaçamento com gap

Como vimos nos exemplos, o gap coloca um espaçamento entre linhas e colunas. Até aqui, usamos grid-column-gap para colunas e grid-row-gap para linhas.

No entanto, você pode simplificar ainda mais o processo com o atalho grid-gap, que aplica um único valor para linhas e colunas:

.grid-container {
    display: grid;
    grid-gap: 20px;
}

Nesse caso, o gap de linhas e colunas fica em 20px. Se você precisar de valores diferentes, pode declarar cada gap separadamente ou usar a sintaxe com dois valores:

.grid-container {
    display: grid;
    grid-gap: 10px 20px;
}

Aqui vale atenção à ordem. O primeiro valor define o espaçamento entre as linhas, e o segundo, o espaçamento entre as colunas.

Ou seja, neste exemplo o row-gap fica em 10px e o column-gap fica em 20px. É uma forma muito prática de preencher as duas propriedades de uma vez.

Gap ou grid-gap no display grid

As primeiras versões da especificação chamavam essas propriedades de grid-gap, grid-row-gap e grid-column-gap. Hoje, o nome padrão é simplesmente gap, row-gap e column-gap.

Mesmo assim, os navegadores continuam aceitando os nomes antigos como aliases, para manter a compatibilidade com sites legados. Portanto, os exemplos acima funcionam, mas em código novo prefira a versão curta:

.grid-container {
    display: grid;
    gap: 10px 20px;
}

Além disso, as propriedades gap, row-gap e column-gap também funcionam no Flexbox. Dessa forma, você usa o mesmo vocabulário nos dois modelos de layout.

Unidades flexíveis com fr e repeat

Nos exemplos anteriores, usamos tamanhos fixos em pixels. Contudo, o display grid fica muito mais poderoso quando as colunas se adaptam ao espaço disponível.

Para isso existe a unidade fr, que representa uma fração do espaço livre do container. Por exemplo, três colunas de 1fr dividem a largura em três partes iguais.

A função repeat(), por sua vez, evita repetir o mesmo valor várias vezes. Assim, repeat(3, 1fr) equivale a escrever 1fr 1fr 1fr.

.grid-container {
    display: grid;
    /* três colunas de mesma largura */
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
}

Também é possível misturar unidades. Por exemplo, 200px 1fr cria uma barra lateral fixa e uma área de conteúdo que ocupa o restante.

Grid explícito e grid implícito

As linhas e colunas que você declara com grid-template-columns e grid-template-rows formam o grid explícito. No entanto, o conteúdo nem sempre cabe nessa estrutura.

Quando sobram itens, o navegador cria novas trilhas automaticamente, formando o grid implícito. Nesse caso, a propriedade grid-auto-rows define o tamanho dessas linhas extras.

Combinada com minmax(), essa propriedade garante uma altura mínima sem cortar conteúdo maior:

.grid-container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    /* linhas extras com no mínimo 100px e altura livre */
    grid-auto-rows: minmax(100px, auto);
}

Na prática, esse padrão é muito comum em listas de cards. Com isso, cada novo card entra na próxima célula livre sem que você precise declarar todas as linhas.

Grid template areas no display grid

Aqui talvez esteja o recurso mais interessante do display grid: criar áreas distintas e cuidar de cada uma de forma exclusiva. Primeiro, você define as áreas no container e, em seguida, vincula cada uma ao estilo do elemento correspondente.

.container {
  display: grid;
  grid-template-areas:
    "header header"
    "menu content";
}

Com a propriedade grid-template-areas, você informa o nome de cada área. Nesse momento, cada valor na horizontal, separado por espaço, vira uma nova coluna.

Já cada string na vertical vira uma nova linha. Portanto, o exemplo acima tem duas linhas com duas colunas cada:

  • "header header": uma linha com duas colunas, ambas ocupadas pelo header.
  • "menu content": uma linha em que a primeira coluna fica com o menu e a segunda com o content, ou seja, o conteúdo em si.

Vinculando elementos com grid-area

Depois de definir as áreas, o próximo passo é vincular cada área ao estilo do header, do menu e do content. Para isso, usamos a propriedade grid-area:

.header {
  grid-area: header;
}
.content {
  grid-area: content;
}
.menu {
  grid-area: menu;
}

Agora, dentro de cada classe, você coloca os estilos separados. Por exemplo, tudo que for do header vai na classe .header, e assim por diante.

Como cada elemento já sabe qual é a sua área, ele respeita o espaço disponível para ele. Dessa forma, o HTML fica limpo e o layout inteiro mora no CSS.

Regras das áreas nomeadas

As áreas seguem algumas regras simples. Primeiro, todas as strings precisam ter o mesmo número de células.

Em seguida, cada área nomeada precisa formar um retângulo. Se o mesmo nome aparecer em formato de L, por exemplo, o navegador considera a declaração inválida.

Por fim, você pode deixar células vazias usando um ponto (.). Assim, o grid reserva o espaço sem associá-lo a nenhum elemento:

.container {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-areas:
    "header header"
    "menu content"
    ". footer";
}

Posicionando itens pelas linhas do display grid

Além das áreas nomeadas, o display grid permite posicionar itens pelas linhas que separam as trilhas. Essas linhas começam no número 1, à esquerda e no topo.

As propriedades grid-column e grid-row recebem a linha inicial e a final, separadas por uma barra:

.featured {
  /* ocupa da linha 1 até a linha 3, ou seja, duas colunas */
  grid-column: 1 / 3;
  grid-row: 1;
}

Nesse exemplo, o item ocupa duas colunas na primeira linha. Por isso, essa técnica é ótima para destacar um card ou um banner dentro de uma lista.

Também é possível usar a palavra span para indicar quantas trilhas o item ocupa. Assim, grid-column: span 2 estende o item por duas colunas a partir da posição em que ele cair.

Alinhando itens no display grid

Cada item ocupa uma célula, mas nem sempre preenche todo o espaço dela. Por isso, o display grid oferece propriedades de alinhamento aplicadas no próprio container.

A propriedade justify-items alinha os itens no eixo horizontal, enquanto align-items cuida do eixo vertical. Ambas aceitam valores como start, end, center e stretch, que é o padrão.

.grid-container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    /* centraliza o conteúdo de cada célula nos dois eixos */
    justify-items: center;
    align-items: center;
}

Quando apenas um item precisa de um alinhamento diferente, use justify-self e align-self diretamente nele. Dessa forma, você ajusta um caso específico sem mexer no restante do layout.

Layouts responsivos com display grid

Um dos padrões mais úteis do display grid combina repeat(), auto-fill e minmax(). Com ele, o navegador decide quantas colunas cabem na tela, sem nenhuma media query.

.cards {
    display: grid;
    /* cria quantas colunas couberem, cada uma com no mínimo 200px */
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 16px;
}

Em uma tela larga, o grid pode exibir quatro ou cinco cards por linha. Já no celular, os mesmos cards se reorganizam em uma única coluna.

As áreas nomeadas também combinam bem com media queries. Por exemplo, você pode empilhar header, menu e conteúdo em telas pequenas e trocar apenas o grid-template-areas em telas maiores:

.container {
  display: grid;
  grid-template-areas:
    "header"
    "menu"
    "content";
}

@media (min-width: 768px) {
  .container {
    grid-template-columns: 200px 1fr;
    grid-template-areas:
      "header header"
      "menu content";
  }
}

Com isso, o HTML continua o mesmo e somente o CSS muda conforme a largura da tela.

Inspecionando o layout no navegador

Quando um item não aparece onde você esperava, as ferramentas de desenvolvedor ajudam bastante. Tanto o Chrome quanto o Firefox exibem uma sobreposição que desenha as linhas, os números e os nomes das áreas do grid.

Para ativar, abra o DevTools, selecione o container e clique no selo "grid" ao lado do elemento. Assim, você enxerga as trilhas, os gaps e as áreas nomeadas diretamente sobre a página.

Na prática, esse recurso economiza muito tempo de tentativa e erro. Afinal, fica claro se o problema está na quantidade de colunas, no gap ou no nome de uma área.

Display grid e Flexbox juntos

O display grid é uma excelente forma de criar layouts flexíveis e, ao mesmo tempo, manter controle total. Além disso, você pode combinar o Grid com o Flexbox para ganhar ainda mais controle e facilidade.

Uma divisão comum é usar o Grid para a estrutura da página e o Flexbox para alinhar o conteúdo dentro de cada área. Por exemplo, o header ocupa a sua área no grid, enquanto os links do menu se alinham com Flexbox.

Se você está começando no front-end, também vale revisar o que você precisa saber antes de aprender HTML. Afinal, um bom layout depende de uma marcação bem estruturada.

Vídeo sobre display grid

No vídeo abaixo, você acompanha os conceitos deste artigo na prática. Assim, fica mais fácil visualizar como cada propriedade do display grid altera o layout.

Curso gratuito: Crie Sites Responsivos

Para aprofundar o assunto, o balta.io oferece o curso gratuito Crie Sites Responsivos. Nele, você aplica layouts que se adaptam a diferentes tamanhos de tela.

Banner do curso gratuito Crie Sites Responsivos do balta.io, que complementa o estudo de display grid
O curso gratuito do balta.io aprofunda a criação de layouts responsivos.

Conferir curso gratuito

Conclusão

O display grid substitui com vantagem os antigos layouts com tabelas, sem perder o controle sobre linhas e colunas. Com poucas propriedades, você define a estrutura inteira da página.

Neste guia, você viu o container, as colunas, as linhas, os gaps, as unidades flexíveis e as áreas nomeadas. Portanto, já tem a base para montar os primeiros layouts com CSS Grid.

Agora, o melhor caminho é praticar: recrie o layout de um site que você usa todos os dias. Bons códigos e até a próxima.

FAQ

Qual a diferença entre display grid e Flexbox?

O Grid organiza o conteúdo em duas dimensões, linhas e colunas ao mesmo tempo. Já o Flexbox trabalha melhor em uma única direção, como uma linha de botões.

O grid-gap ainda funciona?

Sim, os navegadores aceitam grid-gap como alias de gap para manter a compatibilidade. Em código novo, porém, prefira gap, row-gap e column-gap.

Qual a ordem dos valores em gap: 10px 20px?

O primeiro valor define o espaçamento entre as linhas e o segundo, entre as colunas. Com um único valor, o espaçamento vale para os dois eixos.

Os netos do container também viram itens do grid?

Não, apenas os filhos diretos viram itens do grid. Para posicionar elementos mais internos, aplique display: grid também no elemento pai deles.

O que significa a unidade fr?

A unidade fr representa uma fração do espaço livre do container. Por isso, ela é a base de colunas que se adaptam à largura da tela.

Glossário

Termo Significado
Grid container Elemento com display: grid que define o grid e agrupa os itens.
Grid item Filho direto do container, posicionado nas células do grid.
Trilha (track) Uma linha ou coluna do grid.
Célula Menor unidade do grid, na interseção entre uma linha e uma coluna.
Gap Espaçamento entre as linhas e as colunas do grid.
fr Unidade que representa uma fração do espaço livre do container.
Grid explícito Trilhas declaradas com grid-template-columns e grid-template-rows.
Grid implícito Trilhas criadas automaticamente quando os itens não cabem no grid explícito.
Grid area Região retangular nomeada que pode ocupar várias células.
Flexbox Modelo de layout do CSS voltado para alinhamento em uma única direção.

Fontes