Efecto de enfoque de galería CSS puro con :not | trucos CSS

A menudo, en el pasado, tenía que descubrir cómo agregar estilos a todos los elementos del contenedor, pero no el que flota.

Demostración del efecto esperado de «desaparición» en hermanos para permitir a los usuarios «concentrarse» en un elemento específico.

Este efecto requiere seleccionar los hermanos de un elemento retenido. Solía ​​implementar JavaScript para esto agregando o eliminando la clase que define las reglas CSS correctas de mouseenter y mouseleave eventos similares a este:

Aunque el código funciona, mi instinto siempre me dijo que debe haber alguna forma de CSS puro para lograr el mismo resultado.Hace unos años, mientras trabajaba en un cierto control deslizante para mi empresa, se me ocurrió una solución similar a la que Chris Geelhoed Recreé la famosa animación en la página de inicio de Netflix y me di cuenta de que ya no necesitaba JavaScript para esto.

Hace unos meses estaba tratando de implementar el mismo enfoque para un feed basado en cuadrículas en el sitio web de mi empresa y, boom, ¡no funcionó debido a la diferencia entre los elementos!

Por suerte para mí, resultó que no tenía por qué permanecer así y, de nuevo, no necesité JavaScript para ello.

Marcado y CSS básico

Comencemos a codificar preparando el marcado adecuado:

  • .grid está basado en la red <ul> una lista;
  • y .grid__child los elementos son <li> niños con los que queremos comunicarnos.

El marcado se ve así:

<ul class="grid">
  <li class="grid__child"></li>
  <li class="grid__child"></li>
  <li class="grid__child"></li>
</ul>

El estilo debería verse así:

.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 ejemplo creará tres elementos de lista que ocupan tres columnas en una cuadrícula.

El poder de los selectores CSS

Ahora agreguemos un poco de interactividad. El enfoque que implementé originalmente se basó en dos pasos:

  1. pasar el cursor sobre el contenedor debería cambiar los estilos de todos los elementos dentro…
  2. … excepto por el que el cursor se está moviendo actualmente.

Comencemos agarrando a cada niño a medida que el cursor se mueve sobre el contenedor:

.grid:hover .grid__child {
  /* ... */
}

En segundo lugar, apaguemos el elemento sobre el que se muestra actualmente y alejemos opacity a cualquier otro niño:

.grid:hover .grid__child:not(:hover) {
  opacity: 0.3;
}

Y esto sería suficiente para contenedores sin espacios entre elementos secundarios:

GIF animado de un cursor de mouse interactuando con elementos que no están separados por espacios.
Demostración de una solución que funciona perfectamente.

Sin embargo, en mi caso no pude eliminar estos vacíos:

GIF animado del cursor del mouse moviéndose sobre elementos.  Sin embargo, cuando el mouse ingresa en un espacio entre dos elementos, el efecto finaliza cuando el mouse abandona el elemento.
Demostración del problema encontrado al ingresar espacios en blanco.

Cuando moví el mouse entre los mosaicos, todos los elementos secundarios se desvanecieron.

Ignorar espacios

Podemos suponer que los huecos son partes del contenedor que sus elementos secundarios no superponen. No queremos activar el efecto cada vez que el cursor ingresa al contenedor, sino cuando pasa sobre uno de los elementos del interior. ¿Podemos ignorar que el cursor se mueve sobre los espacios?

Sí, podemos, usando pointer-events: none en .grid recipiente y devuélvalos con pointer-events: auto sobre sus hijos:

.grid {
  /* ... */
  pointer-events: none;
}

/* ... */

.grid__child {
  /* ... */
  pointer-events: auto;
}

Solo agreguemos una transición genial a la opacidad y tenemos un componente listo:

Probablemente sea aún más genial cuando agregamos más mosaicos y creamos un diseño 2D:

El CSS final se ve así:

.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;
}

¡Con solo 2 líneas adicionales de código, resolvimos el problema de la brecha!

Posibles problemas

Aunque es una solución compacta, hay algunas situaciones en las que pueden ser necesarias algunas soluciones alternativas.

Desafortunadamente, este truco no funcionará cuando desee que el contenedor se pueda desplazar, como en una especie de control deslizante horizontal. pointer-events: none style ignorará no solo el evento hover, sino también todos los demás. En tales situaciones, puede envolver .grid en otro contenedor, así:

<div class="container">
  <ul class="grid">
    <li class="grid__child"></li>
    <li class="grid__child"></li>
    <li class="grid__child"></li>
    <li class="grid__child"></li>
    <li class="grid__child"></li>
    <li class="grid__child"></li>
    <li class="grid__child"></li>
  </ul>
</div>

Resumen

Le recomiendo encarecidamente que experimente y trate de encontrar un enfoque más simple y natural para las tareas que normalmente se espera que tengan cierto nivel de complejidad. Las tecnologías web como CSS son cada vez más potentes y, al usar soluciones nativas listas para usar, puede lograr excelentes resultados sin tener que mantener su código y proporcionarlo a los proveedores de navegadores.

Espero que hayas disfrutado este breve tutorial y lo hayas encontrado útil. ¡Gracias!

El autor eligió técnico educación para recibir una donación como parte de Escribir para donaciones programa.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

rtp live

Baccarat Online

Bonus New Member

Roulette Online

Sicbo Online

slot gacor