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 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
Agora, cada cartão terá a seguinte estrutura:
1 |
|
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.
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.
- Se virmos a página em um navegador de desktop ou dispositivo com foco, o layout da galeria mudará para isto:
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.
- 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.
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.
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.
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:
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.
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:
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!