Como animar layouts de grade CSS (projeto de grade de imagem)

É isso mesmo – podemos animar algumas das propriedades CSS Grid! Hoje, veremos esse comportamento em ação construindo uma grade de imagens responsiva com efeitos de foco. Aproveitando esta oportunidade, também utilizaremos o poderoso seletor CSS :has().

Vamos começar!

Nossa grade de imagens

Aqui está o que vamos criar: certifique-se de ver a demonstração em tela inteira em uma tela grande (≥900px) e passe o mouse sobre as cartas:

1. A marcação

Começaremos colocando seis cartas dentro de um recipiente. Iremos agrupar os três primeiros e os dois últimos em contêineres aninhados, como você pode ver na marcação abaixo:

1
 class="grid">
2
   class="sub-grid sub-grid-1">
3
     class="card">...
4
     class="card">...
5
     class="card">...
6
  
7
   class="card">...
8
   class="sub-grid sub-grid-2">
9
     class="card">...
10
     class="card">...
11
  
12

Agora, cada cartão terá a seguinte estrutura:

1
 class="card">
2
  
3
     width="IMG_WIDTH" height="IMG_HEIGHT" src="IMG_URL" alt="">
4
    
5
      
6
        ...
7
        
8
          by  href="UNSPLASH_URL" target="_blank">...
9
        
10
      
11
    
12
  
13

2. Os estilos

Em telas pequenas (<900px), todos os cartões serão empilhados e suas informações ficarão visíveis.

O layout móvelO layout móvelO layout móvel

Em telas maiores, teremos um layout de três colunas.

Aqui, haverá dois cenários que serão verificados com a ajuda do hover consulta de mídia:

  • Se virmos a página de um dispositivo que não suporta foco, nossa galeria ficará assim.
O layout da área de trabalho em dispositivos que não suportam foco.O layout da área de trabalho em dispositivos que não suportam foco.O layout da área de trabalho em dispositivos que não suportam foco.
  • Se virmos a página em um navegador de desktop ou dispositivo com foco, o layout da galeria mudará para isto:
O layout da área de trabalho em dispositivos compatíveis com foco.O layout da área de trabalho em dispositivos compatíveis com foco.O layout da área de trabalho em dispositivos compatíveis com foco.

Nesse caso, colocaremos todos os cartões em escala de cinza e ocultaremos seus detalhes. Quando o usuário passa o mouse sobre um cartão, aumentamos seu tamanho e mostramos suas informações. Mais sobre isso em um momento.

Layout de três colunas

Vamos discutir nosso layout de três colunas um pouco mais detalhadamente.

O layout de três colunasO layout de três colunasO layout de três colunas
  • Vamos configurá-lo usando CSS Grid.
  • A primeira coluna terá o dobro do tamanho das outras duas.
  • Dentro da primeira coluna, teremos uma grade aninhada onde a terceira coluna terá o dobro do tamanho das outras duas e ficará abaixo delas. A altura das linhas será de 40vh e personalizável através do --half-height Variável CSS.
  • A altura da primeira coluna será o dobro da altura das outras duas (80vh). Novamente, podemos personalizá-lo através do --height Variável CSS.
  • Dentro da terceira coluna, teremos uma grade aninhada onde as colunas serão empilhadas, e a altura das linhas também será 40vh.

Aqui estão os estilos relacionados:

1
:root {
2
  --height: 80vh;
3
  --half-height: calc(var(--height) / 2);
4
}
5

6
@media (min-width: 900px) {
7
  .grid,
8
  .sub-grid {
9
    display: grid;
10
  }
11

12
  .grid {
13
    grid-template-columns: 2fr 1fr 1fr;
14
  }
15

16
  .sub-grid {
17
    grid-template-rows: var(--half-height) var(--half-height);
18
  }
19

20
  .sub-grid-1 {
21
    grid-template-columns: 1fr 1fr auto;
22
  }
23

24
  .sub-grid-1 .card:last-child {
25
    grid-column: 1/-1;
26
  }
27

28
  /*.sub-grid-2 {

29
    grid-template-columns: 1fr;

30
  }*/
31
}

Efeito de foco

Cada vez que passamos o mouse sobre um cartão/coluna, expandiremos sua largura ou altura para produzir um efeito de zoom. Como usamos CSS Grid para estruturar o layout, temos que atualizar os valores do grid-template-rows e grid-template-columns propriedades ao passar o mouse.

Mas, o problema é o seguinte: essas propriedades são definidas no elemento ancestral e não no próprio cartão. Normalmente, usaríamos JavaScript para atualizá-los, mas felizmente, o :has() seletor relacional torna isso possível.

Animação #1

Vamos ver como esse seletor funciona em ação.

Considere a segunda coluna da nossa grade.

A segunda coluna da nossa gradeA segunda coluna da nossa gradeA segunda coluna da nossa grade

Inicialmente, temos esta regra:

1
.grid {
2
  grid-template-columns: 2fr 1fr 1fr;
3
  transition: all 1s;
4
}

Assim que passarmos o mouse sobre o cartão, ele se expandirá para cobrir toda a largura da grade.

Como a segunda coluna ficará ao passar o mouseComo a segunda coluna ficará ao passar o mouseComo a segunda coluna ficará ao passar o mouse

A regra CSS que fará a mágica é esta:

1
.grid:has(> .card:hover) {
2
  grid-template-columns: 0fr 1fr 0fr;
3
}

A regra acima irá verificar se uma coluna imediata da grade está sendo pairada. Se essa condição for atendida, ele atualizará o valor do grid-template-columns propriedade para que a primeira e a terceira colunas fiquem ocultas enquanto a primeira se expande para ocupar seu espaço.


Usar 0fr em vez de 0 para fazer a animação funcionar!

Animação #2

Vejamos outro exemplo.

Considere a primeira coluna aninhada da primeira coluna.

A primeira coluna aninhada da primeira coluna.A primeira coluna aninhada da primeira coluna.A primeira coluna aninhada da primeira coluna.

Inicialmente, temos esta regra:

1
.sub-grid-1 {
2
  grid-template-columns: 1fr 1fr auto;
3
  transition: all 1s;
4
}

Assim que passarmos o mouse sobre esse cartão, ele dobrará de tamanho e ocultará o segundo cartão assim:

Qual será a aparência da primeira coluna aninhada da primeira coluna ao passar o mouseQual será a aparência da primeira coluna aninhada da primeira coluna ao passar o mouseQual será a aparência da primeira coluna aninhada da primeira coluna ao passar o mouse

A regra CSS que fará a mágica é esta:

1
.grid:has(.sub-grid-1 .card:first-of-type:hover) .sub-grid-1 {
2
  grid-template-columns: 1fr 0fr auto;
3
}

A regra acima irá verificar se a primeira coluna aninhada da primeira coluna da grade (que atua como um contêiner de grade) está sendo pairada. Se essa condição for atendida, ele atualizará o valor do grid-template-columns propriedade para que a segunda coluna aninhada fique oculta enquanto a primeira se expande para ocupar seu espaço.

Use 0fr em vez de 0 para fazer a animação funcionar!

Animação #3

Vamos terminar com outro exemplo.

Considere a primeira coluna aninhada da terceira coluna.

A primeira coluna aninhada da terceira coluna.A primeira coluna aninhada da terceira coluna.A primeira coluna aninhada da terceira coluna.

Inicialmente, temos esta regra:

1
.sub-grid-2 {
2
  grid-template-rows: 40vh 40vh;
3
  transition: all 1s;
4
}

Assim que passarmos o mouse sobre esse cartão, ele dobrará sua altura e ocultará o segundo cartão assim:

Qual será a aparência da primeira coluna aninhada da terceira coluna ao passar o mouseQual será a aparência da primeira coluna aninhada da terceira coluna ao passar o mouseQual será a aparência da primeira coluna aninhada da terceira coluna ao passar o mouse

A regra CSS que fará a mágica é esta:

1
.grid:has(.sub-grid-2 .card:first-of-type:hover) .sub-grid-2 {
2
  grid-template-rows: 80vh 0;
3
}

A regra acima irá verificar se a primeira coluna aninhada da terceira coluna da grade (que atua como um contêiner de grade) está sendo pairada. Se essa condição for atendida, ele atualizará o valor do grid-template-rows propriedade para que a segunda coluna aninhada fique oculta enquanto a primeira se expande verticalmente para ocupar seu espaço.

Você pode ver o resto dos estilos clicando no CSS guia da demonstração – usei aninhamento CSS para os estilos de cartão.

Conclusão

Feito! Durante este tutorial, aprendemos como animar layouts de grade CSS com a ajuda do poderoso :has() Pseudoclasse CSS. Esperamos que você tenha gostado do nosso projeto e adquirido novos conhecimentos.

Novamente, aqui está o que construímos hoje:

Como sempre, muito obrigado pela leitura!

Deixe uma resposta