Muitas vezes, no passado, eu precisava descobrir como adicionar estilos a todos os elementos dentro do contêiner, mas não o pairado.
Este efeito requer a seleção dos irmãos de um elemento pairado. Eu costumava aplicar JavaScript para isso, adicionando ou removendo a classe que definia as regras CSS apropriadas em mouseenter
e mouseleave
eventos semelhantes a este:
Embora o código faça o truque, meu pressentimento sempre me disse que deve haver alguma maneira de CSS puro para alcançar o mesmo resultado. Alguns anos atrás, enquanto trabalhava em um determinado controle deslizante para minha empresa, criei uma solução semelhante a como Chris Geelhoed recriou a famosa animação da página inicial da Netflix e entendi que não precisava mais de JavaScript para isso.
Alguns meses atrás, eu estava tentando implementar a mesma abordagem para um feed baseado em grade no site da minha empresa e — bum — não funcionou por causa da lacuna entre os elementos!
Felizmente para mim, parecia que não precisava ficar assim, e mais uma vez eu não precisava de JavaScript para isso.
Marcação e CSS básico
Vamos começar a codificar preparando a marcação adequada:
.grid
é baseado em gradeLista;
- e
.grid__child
elementos são
crianças com quem queremos interagir.
A marcação fica assim:
O estilo deve ficar assim:
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, 15rem);
grid-gap: 1rem;
}
.grid__child {
background: rgba(0, 0, 0, .1);
border-radius: .5rem;
aspect-ratio: 1/1;
}
Este código de exemplo criará três itens de lista ocupando três colunas em uma grade.
O poder dos seletores CSS
Agora, vamos adicionar alguma interatividade. A abordagem que apliquei inicialmente foi baseada em duas etapas:
- passar o mouse sobre o contêiner deve alterar os estilos de todos os elementos dentro…
- …exceto aquele que o cursor está pairando no momento.
Vamos começar pegando todos os filhos enquanto o cursor está pairando sobre o contêiner:
.grid:hover .grid__child {
/* ... */
}
Em segundo lugar, vamos excluir o item em foco no momento e reduzir o opacity
de qualquer outra criança:
.grid:hover .grid__child:not(:hover) {
opacity: 0.3;
}
E isso seria perfeitamente suficiente para contêineres sem lacunas entre os elementos filhos:
No entanto, no meu caso, não consegui remover essas lacunas:
Quando eu estava movendo o mouse entre os blocos, todos os elementos filhos estavam desaparecendo.
Ignorando as lacunas
Podemos supor que as lacunas são partes do contêiner que não são sobrepostas por seus filhos. Não queremos executar o efeito toda vez que o cursor entrar no container, mas sim quando ele passar o mouse sobre um dos elementos dentro dele. Podemos ignorar o cursor se movendo acima das lacunas então?
Sim, podemos, usando pointer-events: none
na .grid
recipiente e trazê-los de volta com pointer-events: auto
em seus filhos:
.grid {
/* ... */
pointer-events: none;
}
/* ... */
.grid__child {
/* ... */
pointer-events: auto;
}
Vamos apenas adicionar uma transição legal na opacidade e temos um componente pronto:
Provavelmente é ainda mais legal quando adicionamos mais blocos e criamos um layout bidimensional:
O CSS final fica assim:
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, 15rem);
grid-gap: 3rem;
pointer-events: none;
}
.grid:hover .grid__child:not(:hover) {
opacity: 0.3;
}
.grid__child {
background: rgba(0, 0, 0, .1);
border-radius: .5rem;
aspect-ratio: 1/1;
pointer-events: auto;
transition: opacity 300ms;
}
Com apenas 2 linhas adicionais de código, superamos o problema da lacuna!
Possíveis problemas
Embora seja uma solução compacta, existem algumas situações em que pode exigir algumas soluções alternativas.
Infelizmente, esse truque não funcionará quando você quiser que o contêiner seja rolável, por exemplo, como em algum tipo de controle deslizante horizontal. o pointer-events: none
style iria ignorar não apenas o evento hover, mas todos os outros também. Em tais situações, você pode embrulhar o .grid
em outro container, assim:
Resumo
Eu encorajo você a experimentar e tentar encontrar uma abordagem mais simples e nativa para tarefas que normalmente devem ter algum nível de complexidade. As tecnologias da Web, como CSS, estão ficando cada vez mais poderosas e, usando soluções nativas prontas para uso, você pode obter ótimos resultados sem a necessidade de manter seu código e cedê-lo a fornecedores de navegadores.
Espero que você tenha gostado deste pequeno tutorial e o tenha achado útil. Obrigado!
O autor selecionou o Tecnologia Educação receber uma doação como parte do Escreva para doações .