Rayas de fondo animadas que hacen la transición al pasar el mouse PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.

Rayas de fondo animadas que cambian al pasar el mouse por encima

¿Con qué frecuencia busca el CSS? background-size ¿propiedad? Si eres como yo, y probablemente como muchas otras personas de front-end, generalmente es cuando background-size: cover una imagen para llenar el espacio de un elemento completo.

Bueno, se me presentó un desafío interesante que requería un tamaño de fondo más avanzado: franjas de fondo que cambian al pasar el mouse por encima. Mira esto y muévelo con el cursor:

Están sucediendo muchas más cosas además del tamaño del fondo, pero ese era el truco que necesitaba para que las rayas hicieran la transición. Pensé en mostrarles cómo llegué allí, no solo porque creo que es un efecto visual realmente agradable, sino porque me exigió ser creativo con degradados y modos de fusión que creo que podrían disfrutar.

Comencemos con una configuración muy básica para simplificar las cosas. Estoy hablando de un solo

en el HTML que tiene el estilo de un cuadrado verde:

div {
  width: 500px;
  height: 500px;
  background: palegreen;
}
Rayas de fondo animadas que cambian al pasar el mouse por encima

Configuración de las franjas de fondo

Si su mente fue directamente a un degradado lineal de CSS cuando vio esas rayas, entonces ya estamos en la misma página. No podemos hacer exactamente un degradado repetitivo en este caso, ya que queremos que las franjas ocupen cantidades desiguales de espacio y hacer la transición, pero podemos crear cinco franjas encadenando cinco fondos encima de nuestro color de fondo existente y colocándolos en la parte superior. -derecha del contenedor:

div {
  width: 500px;
  height: 500px;
  background: 
    linear-gradient(black, black) top right,
    linear-gradient(black, black) top 100px right,
    linear-gradient(black, black) top 200px right,
    linear-gradient(black, black) top 300px right,
    linear-gradient(black, black) top 400px right, 
    palegreen;
}

Hice rayas horizontales, pero también podríamos ir verticales con el enfoque que estamos cubriendo aquí. Y podemos simplificar esto un poco con propiedades personalizadas:

div {
  --gt: linear-gradient(black, black);
  --n: 100px;

  width: 500px;
  height: 500px;
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    palegreen;
}

Por lo tanto, la --gt el valor es el gradiente y --n es una constante que estamos usando para empujar las rayas hacia abajo para que se desplacen verticalmente. Y es posible que haya notado que no he establecido un degradado real, sino rayas negras sólidas en el linear-gradient() función: eso es intencional y veremos por qué lo hice en un momento.

Una cosa más que debemos hacer antes de continuar es evitar que nuestros fondos se repitan; de lo contrario, formarán mosaicos y llenarán todo el espacio:

div {
  --gt: linear-gradient(black, black);
  --n: 100px;

  width: 500px;
  height: 500px;
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    palegreen;
  background-repeat: no-repeat;
}

Podríamos haber establecido background-repeat existentes background taquigrafía, pero decidí dividirlo aquí para mantener las cosas fáciles de leer.

Compensando las rayas

Técnicamente tenemos rayas, pero es bastante difícil saberlo porque no hay espacio entre ellas y cubren todo el contenedor. Es más como si tuviéramos un cuadrado negro sólido.

Aquí es donde podemos usar el background-size propiedad. Queremos establecer tanto la altura como el ancho de las franjas y la propiedad admite una sintaxis de dos valores que nos permite hacer exactamente eso. Y podemos encadenar esos tamaños separándolos con comas de la misma manera que lo hicimos en background.

Comencemos de manera simple configurando primero los anchos. Usando la sintaxis de un solo valor para background-size establece el ancho y por defecto la altura a auto. Estoy usando valores totalmente arbitrarios aquí, así que establezca los valores que funcionen mejor para su diseño:

div {
  --gt: linear-gradient(black, black);
  --n: 100px;

  width: 500px;
  height: 500px;
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    palegreen;
  background-repeat: no-repeat;
  background-size: 60%, 90%, 70%, 40%, 10%;
}

Si está usando los mismos valores que yo, obtendrá esto:

No parece exactamente que establecimos el ancho de todas las franjas, ¿verdad? Eso es debido a la auto comportamiento de altura de la sintaxis de valor único. La segunda franja es más ancha que las otras debajo y las cubre. Debemos establecer las alturas para que podamos ver nuestro trabajo. Todos deben tener la misma altura y podemos reutilizar nuestro --n variable, de nuevo, para simplificar las cosas:

div {
  --gt: linear-gradient(black, black);
  --n: 100px;

  width: 500px;
  height: 500px;
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    palegreen;
    background-repeat: no-repeat;
    background-size: 60% var(--n), 90% var(--n), 70% var(--n), 40% var(--n), 10% var(--n); // HIGHLIGHT 15
}

¡Ay, mucho mejor!

Agregar espacios entre las rayas

Este es un paso totalmente opcional si su diseño no requiere espacios entre las rayas, pero el mío sí y no es demasiado complicado. Cambiamos la altura de cada raya background-size una pizca, disminuyendo el valor por lo que no llegan a llenar el espacio vertical completo.

Podemos seguir usando nuestro --n variable, pero restar una pequeña cantidad, digamos 5px, utilizando calc() para conseguir lo que queremos.

background-size: 60% calc(var(--n) - 5px), 90% calc(var(--n) - 5px), 70% calc(var(--n) - 5px), 40% calc(var(--n) - 5px), 10% calc(var(--n) - 5px);

Esa es una gran cantidad de repeticiones que podemos eliminar con otra variable:

div {
  --h: calc(var(--n) - 5px);
  /* etc. */
  background-size: 60% var(--h), 90% var(--h), 70% var(--h), 40% var(--h), 10% var(--h);
}

Enmascaramiento y mezcla

Ahora vamos a intercambiar el palegreen color de fondo que hemos estado usando con fines visuales hasta este punto para el blanco.

div {
  /* etc. */
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    #fff;
  /* etc. */
}

Un patrón en blanco y negro como este es perfecto para enmascarar y mezclar. Para hacer eso, primero vamos a envolver nuestro

en un nuevo contenedor principal e introducir un segundo

bajo ello:

Vamos a hacer un poco de refactorización de CSS aquí. Ahora que tenemos un nuevo contenedor principal, podemos pasar el fijo width y height propiedades que estábamos usando en nuestro

Por ahí:

section {
  width: 500px;
  height: 500px;
} 

También voy a usar CSS Grid para posicionar los dos

elementos uno encima de otro. Este es el mismo truco que usa Temani Afif para crear su galerías de imágenes súper geniales. La idea es que coloquemos ambos divs sobre el contenedor completo usando el grid-area propiedad y alinear todo hacia el centro:

section {
  display: grid;
  align-items: center;
  justify-items: center;
  width: 500px;
  height: 500px;
} 

section > div {
  width: inherit;
  height: inherit;
  grid-area: 1 / 1;
}

Ahora, mira esto. La razón por la que usé un degradado sólido que va de negro a negro anteriormente es para prepararnos para enmascarar y mezclar los dos

capas. Esto no es un verdadero enmascaramiento en el sentido de que estamos llamando al mask propiedad, pero el contraste entre las capas controla qué colores son visibles. El área cubierta por blanco permanecerá blanca y el área cubierta por fugas negras. Documentación de MDN sobre modos de mezcla tiene una buena explicación de cómo funciona esto.

Para que funcione, aplicaré el degradado real que queremos ver en la primera

al aplicar las reglas de estilo de nuestro inicial

en el nuevo, usando el :nth-child() pseudo-selector:

div:nth-child(1) { 
  background: linear-gradient(to right, red, orange); 
}

div:nth-child(2)  {
  --gt: linear-gradient(black, black);
  --n: 100px;
  --h: calc(var(--n) - 5px);
  background: 
    var(--gt) top right,
    var(--gt) top var(--n) right,
    var(--gt) top calc(var(--n) * 2) right,
    var(--gt) top calc(var(--n) * 3) right,
    var(--gt) top calc(var(--n) * 4) right, 
    white;
  background-repeat: no-repeat;
  background-size: 60% var(--h), 90% var(--h), 70% var(--h), 40% var(--h), 10% var(--h);
}

Si nos detenemos aquí, en realidad no veremos ninguna diferencia visual con respecto a lo que teníamos antes. Eso es porque aún no hemos hecho la mezcla real. Entonces, hagámoslo ahora usando el screen modo de mezcla:

div:nth-child(2)  {
  /* etc. */
  mix-blend-mode: screen;
}

Usé un color de fondo beige en la demostración que mostré al principio de este artículo. Ese tipo de color blanquecino ligeramente más oscuro permite que un poco de color se desvanezca en el resto del fondo:

El efecto de desplazamiento

La última pieza de este rompecabezas es el efecto de desplazamiento que ensancha las franjas a todo lo ancho. Primero, escribamos nuestro selector para ello. Queremos que esto suceda cuando el contenedor principal (

en nuestro caso) está suspendido. Cuando se desplace, cambiaremos el tamaño de fondo de las franjas contenidas en el segundo

:

/* When 
is hovered, change the second div's styles */ section:hover > div:nth-child(2){ /* styles go here */ }

Querremos cambiar el background-size de las franjas en todo el ancho del contenedor manteniendo la misma altura:

section:hover > div:nth-child(2){
  background-size: 100% var(--h);
}

Eso "ajusta" el fondo a todo el ancho. Si le agregamos un poco transition a esto, luego vemos que las rayas se expanden al pasar el mouse:

section:hover > div:nth-child(2){
  background-size: 100% var(--h);
  transition: background-size 1s;
}

Aquí está esa demostración final una vez más:

Solo agregué texto allí para mostrar cómo se vería usar esto en un contexto diferente. Si hace lo mismo, vale la pena asegurarse de que haya suficiente contraste entre el color del texto y los colores utilizados en el degradado para cumplir con Directrices WCAG. Y mientras nos referimos brevemente a la accesibilidad, vale la pena teniendo en cuenta las preferencias del usuario para el movimiento reducido cuando se trata del efecto de desplazamiento.

¡Eso es un envoltorio!

Bastante ordenado, ¿verdad? Ciertamente lo creo. Lo que me gusta de esto también es que es bastante fácil de mantener y personalizable. Por ejemplo, podemos alterar la altura, los colores y la dirección de las rayas cambiando algunos valores. Incluso puede variar algunas cosas más allí, como los colores y los anchos, para que sea aún más configurable.

Estoy realmente interesado si hubiera abordado esto de una manera diferente. Si es así, por favor comparte en los comentarios! Sería bueno ver cuántas variaciones podemos recopilar.

Sello de tiempo:

Mas de Trucos CSS