Artigo original: How to create an image gallery with CSS Grid

Galerias de imagens feitas por sites da web como o Unsplash e o Pinterest, entre outros, são feitas com técnicas como posicionamento ou tradução do item da imagem, bastante pesadas de se fazer. Você pode obter a mesma funcionalidade rapidamente com o uso do CSS Grid.

Por exemplo: na imagem da capa, temos uma galeria com imagens de larguras e alturas variadas, um caso de uso perfeito para o CSS Grid.

Vamos começar!

A grade por baixo dos panos

Vamos criar uma grade de 8x8. Podemos criar grades de outros tamanhos, mas isso dependerá do tipo de galeria que você quer. em nosso caso, uma grade de 8x8 será o ideal.

  • Um contêiner de grade é definido ajustando a propriedade display de um elemento como grid. Desse modo, a div com a classe grid será nosso contêiner da grade.
  • Usamos a propriedade grid-template-columns para definir as trilhas de colunas e grid-template-rows para definir as trilhas de linhas. Declaramos essas propriedades no contêiner da grade. Em nosso exemplo, faremos um contêiner para uma grade de 8x8.
  • grid-gap: define o tamanho do gap (lacuna) entre linhas e entre colunas em um layout de grade. O valor de grid-gap pode estar em qualquer unidade de comprimento do CSS. Em nosso exemplo, demos um valor de 15px para dar à nossa grade uma aparência melhor.

HTML:

<div class="gallery"></div>

CSS:

.gallery {
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    grid-template-rows: repeat(8, 5vw);
    grid-gap: 15px;
}
Observação: a altura das linhas está, no exemplo, associada à largura do viewport, de modo que cada célula mantenha a taxa de proporção adequada. Temos 8 linhas, cada uma com a altura de 5 viewport width (5 "partes" da largura do viewport). Experimentando com as alturas, chegamos à conclusão de que 5% da largura do viewport era o tamanho perfeito para a altura. Fazemos isso definindo a altura da linha como 5vw (viewport width).
Observação: todos os elementos filhos diretos do contêiner grid serão grid items (itens da grade) automaticamente.

Inserindo itens da grade

Agora, vamos inserir os itens da grade no contêiner da grade:

<div class=”gallery”>
  <figure class=”gallery__item gallery__item--1">
    <img src="img/image-1.jpg" class="gallery__img" alt="Image 1">
  </figure>
  <figure class="gallery__item gallery__item--2">
    <img src="img/image-2.jpg" class="gallery__img" alt="Image 2">
  </figure>
  <figure class="gallery__item gallery__item--3">
    <img src="img/image-3.jpg" class="gallery__img" alt="Image 3">
  </figure>
  <figure class="gallery__item gallery__item--4">
    <img src="img/image-4.jpg" class="gallery__img" alt="Image 4">
  </figure>
  <figure class="gallery__item gallery__item--5">
    <img src="img/image-5.jpg" class="gallery__img" alt="Image 5">
  </figure>
  <figure class="gallery__item gallery__item--6">
    <img src="img/image-6.jpg" class="gallery__img" alt="Image 6">
  </figure>
</div>

Estilizando as imagens

.gallery__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

Definir o valor de object fit como cover é como definir o valor de background size como cover para background image. Fazemos isso de modo que a imagem possa preencher a altura e a largura de sua caixa (o item da grade), mantendo sua taxa de proporção.

Observação: a propriedade object fit funciona apenas se definirmos as propriedades width e height.
1_FBsVH1n06ufBr_WcB_xDDQ
Observação: por padrão, os itens da grade são dispostos de acordo com as regras de autocolocação da grade.

Posicionando itens da grade

Antes de começarmos a posicionar os itens da grade, estudaremos alguns conceitos básicos.

A div da grade é o contêiner da grade. Todos os elementos que são filhos diretos dela são os itens da grade. Quando definimos as trilhas da grade (grid tracks, em inglês) com grid-template-columns e com grid-template-rows, a grade nos fornece linhas "numeradas", chamadas de linhas da grade (grid lines, em inglês), para que as usemos para posicionar os itens. Você pode fazer referência a cada linha da grade por meio de um índice numérico.

As colunas começam no número um, da esquerda para a direita, por padrão, enquanto as linhas começam do número um, mas de cima para baixo. São necessárias duas linhas de grade para criar uma única linha ou coluna, uma linha de cada lado, Assim, nossa grade de 8 colunas e 8 linhas consiste em
9 linhas que demarcam as colunas e 9 linhas que demarcam as fileiras ou linhas.

As linhas verticais 1 e 2 determinam os pontos de início e fim da primeira coluna. As linhas 2 e 3 demarcam a segunda coluna e assim por diante. Do mesmo modo, as linhas horizontais 1 e 2 determinam a posição da primeira fileira ou linha, as linhas 2 e 3 demarcam a segunda etc. Saber os conceitos acima ajudará você a entender como posicionaremos os itens (imagens) em nossa grade.

Agora, usaremos os números das linhas de grade para controlar o modo como os itens são dispostos aplicando propriedades diretamente a um item da grade. Podemos especificar em que linha um item da grade começa e termina, bem como por quantas trilhas ele deve se expandir.

1º item da grade

Vamos, então, criar uma nova regra que tenha como alvo o primeiro item da grade. Primeiro, usaremos a propriedade grid-column-start para indicar a linha de grade da coluna onde o primeiro item da grade iniciará. A propriedade grid-column-end indicará onde o primeiro item da grade termina.

Desse modo, o valor de grid-column-start será um número que indica a linha de grade na borda esquerda da coluna. O valor de grid-column-end indicará o valor que marca a borda da direita da coluna.

No exemplo que veremos abaixo, definir grid-column-start como 1 e grid-column-end como 3 significa que o item da grade começará na borda esquerda da grade, percorrendo da linha 1 até a linha 3, preenchendo 2 colunas. Também usaremos as propriedades grid-row-start e grid-row-end para indicar as posições de início e fim do item da grade nas linhas de grade da fileira ou linha do mesmo modo que fizemos com a coluna.

.gallery__item--1 {
    grid-column-start: 1;
    grid-column-end: 3;
    grid-row-start: 1;
    grid-row-end: 3;
}
1_ScnDXtFn-7wffVN62rqg5w
Colocação do primeiro item
Observação: agora, posicionaremos outros itens com base nos mesmos princípios que aprendemos acima.

2º item da grade

.gallery__item--2 {
    grid-column-start: 3;
    grid-column-end: 5;
    grid-row-start: 1;
    grid-row-end: 3;
}
1_U-OLT0CdIjjxvaV-4YpjLg
Colocação do segundo item

3º item da grade

.gallery__item--3 {
    grid-column-start: 5;
    grid-column-end: 9;
    grid-row-start: 1;
    grid-row-end: 6;
}
1_wEZB6kvCDGquI_PH1yH4gQ
Colocação do terceiro item

4º item da grade

.gallery__item--4 {
    grid-column-start: 1;
    grid-column-end: 5;
    grid-row-start: 3;
    grid-row-end: 6;
}
1_AkEoMuGUJM5oB7q-2SLnxA
Colocação do quarto item

5º item da grade

.gallery__item--5 {
    grid-column-start: 1;
    grid-column-end: 5;
    grid-row-start: 6;
    grid-row-end: 9;
}
1_0SA_xLddgWzrV7y0hK8kEQ
Colocação do quinto item

6º item da grade

.gallery__item--6 {
    grid-column-start: 5;
    grid-column-end: 9;
    grid-row-start: 6;
    grid-row-end: 9;
}
1_rmUZZ0lsviNcnofEoAnRPw
Colocação do sexto item

Você encontrará o código completo abaixo.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">

        <link href="https://fonts.googleapis.com/css?family=Josefin+Sans:300,400,400i|Nunito:300,300i" rel="stylesheet">
        <link rel="stylesheet" href="css/style.css">
        <link rel="shortcut icon" type="image/png" href="img/favicon.png">

        <title>Galeria com CSS Grid</title>
    </head>
    <body>
        <div class="container">
            <div class="gallery">
                <figure class="gallery__item gallery__item--1">
                    <img src="img/image-1.jpg" alt="Gallery image 1" class="gallery__img">
                </figure>
                <figure class="gallery__item gallery__item--2">
                    <img src="img/image-2.jpg" alt="Gallery image 2" class="gallery__img">
                </figure>
                <figure class="gallery__item gallery__item--3">
                    <img src="img/image-3.jpg" alt="Gallery image 3" class="gallery__img">
                </figure>
                <figure class="gallery__item gallery__item--4">
                    <img src="img/image-4.jpg" alt="Gallery image 4" class="gallery__img">
                </figure>
                <figure class="gallery__item gallery__item--5">
                    <img src="img/image-5.jpg" alt="Gallery image 5" class="gallery__img">
                </figure>
                <figure class="gallery__item gallery__item--6">
                    <img src="img/image-6.jpg" alt="Gallery image 6" class="gallery__img">
                </figure>
            </div>
        </div>
    </body>
</html>

E o CSS:

*,
*::after,
*::before {
  margin: 0;
  padding: 0;
  box-sizing: inherit; 
}

html {
  box-sizing: border-box;
  font-size: 62.5%; 
}

body {
  font-family: "Nunito", sans-serif;
  color: #333;
  font-weight: 300;
  line-height: 1.6; 
}

.container {
  width: 60%;
  margin: 2rem auto; 
}

.gallery {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  grid-template-rows: repeat(8, 5vw);
  grid-gap: 1.5rem; 
}

.gallery__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block; 
}

.gallery__item--1 {
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 3;

  /** Sintaxe alternativa **/
  /* grid-column: 1 / span 2;  */
  /* grid-row: 1 / span 2; */
}

.gallery__item--2 {
  grid-column-start: 3;
  grid-column-end: 5;
  grid-row-start: 1;
  grid-row-end: 3;

  /** Sintaxe alternativa **/
  /* grid-column: 3 / span 2;  */
  /* grid-row: 1 / span 2; */
}

.gallery__item--3 {
  grid-column-start: 5;
  grid-column-end: 9;
  grid-row-start: 1;
  grid-row-end: 6;

  /** Sintaxe alternativa **/
  /* grid-column: 5 / span 4;
  grid-row: 1 / span 5; */
}

.gallery__item--4 {
  grid-column-start: 1;
  grid-column-end: 5;
  grid-row-start: 3;
  grid-row-end: 6;

  /** Sintaxe alternativa **/
  /* grid-column: 1 / span 4;  */
  /* grid-row: 3 / span 3; */
}

.gallery__item--5 {
  grid-column-start: 1;
  grid-column-end: 5;
  grid-row-start: 6;
  grid-row-end: 9;

  /** Sintaxe alternativa **/
  /* grid-column: 1 / span 4; */
  /* grid-row: 6 / span 3; */
}

.gallery__item--6 {
  grid-column-start: 5;
  grid-column-end: 9;
  grid-row-start: 6;
  grid-row-end: 9;

  /** Sintaxe alternativa **/
  /* grid-column: 5 / span 4; */
  /* grid-row: 6 / span 3; */
}

Você pode tentar adicionar seu próprio CSS para fazer com que essa galeria tenha a aparência que você quiser que ela tenha. Você também pode criar galerias de imagens mais complexas com facilidade.

Aprenda mais sobre o CSS Grid no link fornecido abaixo (em inglês):

A Complete Guide to Grid | CSS-Tricks

Esperamos que você tenha achado este artigo informativo e útil. Seus comentários são bem-vindos!

Obrigado pela leitura!