CSS

Grandes efectos de retención que utilizan propiedades de fondo. trucos CSS

Hace algún tiempo, Jeff escribió un artículo sobre el efecto de retención en frío. El efecto se basa en una combinación de pseudoelementos CSS, transformaciones y transiciones. Muchos comentarios muestran que se puede lograr el mismo efecto con la ayuda de propiedades de fondo. Jeff mencionó que ese era su pensamiento original, y eso es lo que pensé. No digo que el pseudoelemento con el que se encontró sea malo, pero conocer diferentes métodos para lograr el mismo efecto solo puede ser bueno.

En esta publicación, revisaremos este efecto de retención del cursor, pero también lo extenderemos a otros tipos de efectos de retención del cursor que usan solo CSS. background Propiedades.

Puedes ver background propiedades del trabajo en esta demostración, y cómo podemos usar propiedades personalizadas y calc() característica para hacer aún más ¡Aprenderemos cómo combinar todo esto para tener un código bien optimizado!

Efecto de retención del cursor №1

Comencemos con el primer efecto, que es una reproducción del descrito en detalle por Jeff en su artículo, el código utilizado para lograr este efecto es el siguiente:

.hover-1 {
  background: linear-gradient(#1095c1 0 0) var(--p, 0) / var(--p, 0) no-repeat;
  transition: .4s, background-position 0s;
}
.hover-1:hover {
  --p: 100%;
  color: #fff;
}

Si perdemos la transición de color (que es opcional), solo necesitamos tres declaraciones CSS para lograr el efecto. Probablemente se sorprenda de lo pequeño que es el código, pero verá cómo llegamos allí.

Primero, empecemos con lo simple. background-size transición:

Animamos el tamaño del degradado lineal desde 0 100% para 100% 100%Esto significa que el ancho es de 0 para 100% mientras que el fondo en sí permanece de cuerpo entero. Nada complicado todavía.

Comencemos nuestras optimizaciones. Primero, transformamos nuestro gradiente para usar el color solo una vez:

background-image: linear-gradient(#1095c1 0 0);

La sintaxis puede parecer un poco extraña, pero le decimos al navegador que se aplica un color a dos paradas de color, y eso es suficiente para definir un degradado en CSS. Los frenos de ambos colores son 0por lo que el navegador automáticamente hace lo último 100% y llena nuestro degradado con el mismo color. ¡Atajos, FTW!

S background-sizepodemos omitir la altura porque los gradientes son de altura completa por defecto. Podemos hacer la transición de background-size: 0 para background-size: 100%.

.hover-1 {
  background-image: linear-gradient(#1095c1 0 0);
  background-size: 0;
  background-repeat: no-repeat;
  transition: .4s;
}
.hover-1:hover {
  background-size: 100%;
}

Introduzcamos una propiedad personalizada para evitar la duplicación. background-size:

.hover-1 {
  background-image: linear-gradient(#1095c1 0 0);
  background-size: var(--p, 0%);
  background-repeat: no-repeat;
  transition: .4s;
}
.hover-1:hover {
  --p: 100%;
}

no definimos --p inicialmente para que el valor de la reserva (0% en nuestro caso) se utilizará. Cuando mantiene presionado el cursor, definimos un valor que reemplaza la copia de seguridad ( 100%).

Ahora combinemos todas las propiedades de fondo, usando la versión abreviada, para obtener:

.hover-1 {
  background: linear-gradient(#1095c1 0 0) left / var(--p, 0%) no-repeat;
  transition: .4s;
}
.hover-1:hover {
  --p: 100%;
}

¡Nos acercamos! Tenga en cuenta que ingresé un left valor por background-position), que es obligatorio a la hora de determinar el importe en background Además, lo necesitamos de todos modos para lograr el efecto de retención del cursor.

También necesitamos actualizar la posición al sostener el cursor. Esto lo podemos hacer en dos pasos:

  1. Aumente el tamaño a la derecha mientras mantiene presionado el mouse.
  2. Reduzca el tamaño a la izquierda del mouse hacia afuera.

Para hacer esto, necesitamos actualizar background-position y al sostener el mouse:

Agregamos dos cosas a nuestro código:

  • UN background-position valor de right al sostener el mouse
  • UN transition-duration sobre 0s sobre background-position

Esto significa que cuando mantiene presionado el mouse, cambiamos inmediatamente background-position desde left (¡mira, necesitábamos ese valor!) para right por lo que el tamaño del fondo aumentará en el lado derecho Luego, cuando el cursor del mouse abandona el enlace, la transición se realiza en la dirección opuesta, desde right para leftlo que hace que parezca que estamos reduciendo el tamaño del fondo de la izquierda. ¡Nuestro efecto de retención de ratón está listo!

Pero dijiste que solo necesitamos tres declaraciones, y hay cuatro.

Así es, una buena captura left y right Los valores se pueden cambiar a 0 0 y 100% 0respectivamente; y dado que nuestro gradiente ya está en su altura máxima por defecto, podemos obtener con la ayuda 0 y 100%.

.hover-1 {
  background: linear-gradient(#1095c1 0 0) 0 / var(--p, 0%) no-repeat;
  transition: .4s, background-position 0s;
}
.hover-1:hover {
  --p: 100%;
  background-position: 100%;
}

Ver cómo background-position y --p usar los mismos valores? Ahora podemos reducir el código a tres declaraciones:

.hover-1 {
  background: linear-gradient(#1095c1 0 0) var(--p, 0%) / var(--p,0%) no-repeat;
  transition: .4s, background-position 0s;
}
.hover-1:hover {
  --p: 100%;
}

Propiedad personalizada --p determina tanto la posición del fondo como el tamaño. Mantener presionado el cursor actualizará ambos. Este es un caso de uso perfecto que muestra cómo las propiedades personalizadas pueden ayudarnos a reducir el código redundante y evitar escribir propiedades más de una vez. Definimos nuestra configuración a través de propiedades personalizadas y actualizamos este último solo cuando mantenemos presionado el mouse.

Pero el efecto descrito por Jeff hace lo contrario, comenzando por la izquierda y terminando por la derecha ¿Cómo hacemos esto cuando parece que no podemos confiar en la misma variable?

Todavía podemos usar una variable y actualizar ligeramente nuestro código para lograr el efecto contrario. lo que queremos es ir 100% para 0% en cambio 0% para 100%Tenemos una diferencia de 100% que podemos expresar con ayuda calc()como Éste:

.hover-1 {
  background: linear-gradient(#1095c1 0 0) calc(100% - var(--p,0%)) / var(--p,0%) no-repeat;
  transition: .4s, background-position 0s;
}
.hover-1:hover {
  --p: 100%;
}

--p cambiará de 0% para 100%pero la posición de fondo cambiará de 100% para 0%gracias a calc().

Todavía tenemos tres declaraciones y una propiedad personalizada, pero con un efecto diferente.

Antes de pasar al siguiente efecto de retención del cursor, quiero resaltar algo importante que probablemente haya notado. Cuando trato con propiedades personalizadas, uso 0% (con uno) en lugar de sin uno 0Cero sin uno puede funcionar cuando la propiedad personalizada es independiente, pero fallará por dentro calc() donde necesitamos definir explícitamente la unidad. Es posible que necesite otro artículo para explicar esta rareza, pero siempre asegúrese de agregar la unidad cuando trate con propiedades personalizadas. Tengo dos respuestas a StackOverflow (aquí y aquí), que entran en más detalle.

Efecto de retención del cursor №2

Necesitamos una transición más compleja para este efecto. Miremos la ilustración paso a paso para entender lo que está pasando.

Inicialmente, el degradado con una altura fija y un ancho completo está fuera de la vista. Luego mueva el degradado hacia la derecha para cubrir la parte inferior. Finalmente, aumentamos el tamaño del gradiente desde la altura fija hasta 100% para cubrir todo el artículo.

Primero tenemos un background-position transición seguida de una background-size uno. Traduzcamos esto a código:

.hover-2 {
  background-image: linear-gradient(#1095c1 0 0);
  background-size: 100% .08em; /* .08em is our fixed height; modify as needed. */
  background-position: /* ??? */;
  background-repeat: no-repeat;
  transition: background-size .3s, background-position .3s .3s;
}
.hover-2:hover {
  transition: background-size .3s .3s, background-position .3s;
  background-size: 100% 100%;
  background-position: /* ??? */;
}

Tenga en cuenta el uso de dos valores transitorios. Al sostener el mouse, primero debemos cambiar la posición y luego el tamaño, por lo que agregamos un retraso al tamaño. Al retirar el mouse, hacemos lo contrario.

La pregunta ahora es: ¿qué valores usamos? background-positionDejamos estos en blanco arriba background-size los valores son triviales, pero los de background-position no son. Y si mantenemos la configuración real, no podemos mover nuestro gradiente.

Nuestro gradiente tiene un ancho igual a 100%entonces no podemos usar porcentajes background-position moverlo.

Porcentajes utilizados con background-position siempre son un dolor, especialmente cuando los usas por primera vez. Su comportamiento es poco intuitivo, pero bien definido y fácil de entender si entendemos la lógica detrás de él. Creo que se necesitará otro artículo para explicar completamente por qué funciona de esta manera, pero aquí está otra explicación «larga» que publiqué en Stack Overflow¡Te recomiendo que te tomes unos minutos para leer esta respuesta y me lo agradecerás más tarde!

El truco es cambiar el ancho de algo que no sea 100%usemos 200%No nos preocupamos de que el fondo exceda el elemento, porque el desbordamiento está oculto de todos modos.

.hover-2 {
  background-image: linear-gradient(#1095c1 0 0);
  background-size: 200% .08em;
  background-position: 200% 100%;
  background-repeat: no-repeat;
  transition: background-size .3s, background-position .3s .3s;
}
.hover-2:hover {
  transition: background-size .3s .3s, background-position .3s;
  background-size: 200% 100%;
  background-position: 100% 100%;
}

Y esto es lo que obtenemos:

Es hora de optimizar nuestro código. Si tomamos las ideas que aprendimos del primer efecto de retención del cursor, podemos usar propiedades abreviadas y escribir menos declaraciones para que funcione:

.hover-2 {
  background: 
    linear-gradient(#1095c1 0 0) no-repeat
    var(--p, 200%) 100% / 200% var(--p, .08em);
  transition: .3s var(--t, 0s), background-position .3s calc(.3s - var(--t, 0s));
}
.hover-2:hover {
  --p: 100%;
  --t: .3s;
}

Agregamos todas las propiedades de fondo juntas usando la versión abreviada, luego usamos --p para expresar nuestros valores. Las dimensiones cambian de .08em para 100% y la posición de 200% para 100%

También uso otra variable. --t para optimizar la propiedad de transición. Cuando mantenga presionado el mouse, configúrelo en un .3s valor que nos da esto:

transition: .3s .3s, background-position .3s 0s;

cuando sale el raton --t no está definido, por lo que se utilizará el valor de la reserva:

transition: .3s 0s, background-position .3s .3s;

¿No deberíamos tener background-size en transition?

Esta es realmente otra optimización que podemos hacer. Si no especificamos ninguna propiedad, significa «todas» las propiedades, por lo que la transición se define para «todas» las propiedades (incluidas background-size y background-positionLuego se redefine para background-position que es similar a su definición de background-sizeentonces background-position.

«Me gusta» es diferente de decir que algo es «igual». Verá una diferencia si cambia más propiedades mientras mantiene presionado el cursor, por lo que la última optimización puede ser inapropiada en algunos casos.

¿Podemos seguir optimizando el código y usar solo una propiedad personalizada?

¡Si podemos! Anna Tudor compartió un excelente artículo que explica cómo crear SECO cambio, donde una propiedad personalizada puede actualizar múltiples propiedades. No entraré en detalles aquí, pero nuestro código se puede modificar de la siguiente manera:

.hover-2 {
  background: 
    linear-gradient(#1095c1 0 0) no-repeat
    calc(200% - var(--i, 0) * 100%) 100% / 200% calc(100% * var(--i, 0) + .08em);
  transition: .3s calc(var(--i, 0) * .3s), background-position .3s calc(.3s - calc(var(--i, 0) * .3s));
}
.hover-2:hover {
  --i: 1;
}

EN --i la propiedad personalizada inicialmente no está definida, por lo que el valor de reserva 0se usa Sin embargo, cuando mantiene presionado el mouse, cambiamos 0 s 1. Puede calcular para ambos casos y obtener los valores para cada uno. Puede ver esta variable como un «interruptor» que actualiza todos nuestros valores a la vez cuando mantiene presionado el mouse.

Nuevamente, volvamos a solo tres declaraciones de un efecto de retención bastante bueno.

Efecto de retención del cursor №3

Será usamos dos degradados en lugar de uno para este efecto Veremos que la combinación de múltiples degradados es otra forma de crear efectos fantásticos mientras se mantiene presionado el cursor.

Aquí hay un diagrama de lo que hacemos:

Inicialmente, tenemos dos degradados que desbordan el elemento para que no sean visibles. Cada uno de ellos tiene una altura fija y se eleva a la mitad del ancho del elemento. Luego los arrastramos a la vista para hacerlos visibles. El primer gradiente se coloca en la parte inferior izquierda y el segundo en la parte superior derecha. Finalmente, aumentamos la altura para cubrir todo el elemento.

Así es como se ve CSS:

.hover-3 {
  background-image:
    linear-gradient(#1095c1 0 0),
    linear-gradient(#1095c1 0 0);
  background-repeat: no-repeat;
  background-size: 50% .08em;
  background-position:
    -100% 100%,
    200% 0;
  transition: background-size .3s, background-position .3s .3s;
}
.hover-3:hover {
  background-size: 50% 100%;
  background-position:
    0 100%,
    100% 0;  
  transition: background-size .3s .3s, background-position .3s;
}

El código es casi el mismo que el de los otros efectos de retención del cursor que vimos. La única diferencia es que tenemos dos gradientes con dos posiciones diferentes. Los valores de posición pueden parecer extraños, pero nuevamente, esto tiene que ver con cómo funcionan los porcentajes background-position propiedad en CSS, por lo que recomiendo leer el mío Respuesta de desbordamiento de pila si quieres entrar en los detalles aproximados.

¡Ahora vamos a optimizar! Ya entiende la idea: usamos propiedades abreviadas, propiedades personalizadas y calc() poner las cosas en orden.

.hover-3 {
  --c: no-repeat linear-gradient(#1095c1 0 0);
  background: 
    var(--c) calc(-100% + var(--p, 0%)) 100% / 50% var(--p, .08em),
    var(--c) calc( 200% - var(--p, 0%)) 0    / 50% var(--p, .08em);
  transition: .3s var(--t, 0s), background-position .3s calc(.3s - var(--t, 0s));
}
.hover-3:hover {
  --p: 100%;
  --t: 0.3s;
}

Se agregó una propiedad personalizada adicional --clo que determina el gradiente, ya que se utiliza el mismo gradiente en ambos lugares.

yo suelo 50.1% en esta demostración en su lugar 50% para el tamaño del fondo porque evita que se muestre un espacio entre los degradados. también agregué 1% de posiciones por razones similares.

Hagamos la segunda optimización usando el interruptor variable:

.hover-3 {
  --c: no-repeat linear-gradient(#1095c1 0 0);
  background: 
    var(--c) calc(-100% + var(--i, 0) * 100%) 100% / 50% calc(100% * var(--i, 0) + .08em),
    var(--c) calc( 200% - var(--i, 0) * 100%) 0 / 50% calc(100% * var(--i, 0) + .08em);
  transition: .3s calc(var(--i, 0) * .3s), background-position .3s calc(.3s - var(--i, 0) * .3s);
}
.hover-3:hover {
  --i: 1;
}

¿Empezaste a ver los modelos aquí? No es que los efectos que hacemos sean difíciles. Este es más un «último paso» en la optimización del código. Comenzamos escribiendo código detallado con muchas propiedades, luego lo reducimos a reglas simples (por ejemplo, usando taquigrafía, eliminando valores predeterminados, evitando valores redundantes, etc.) para simplificar las cosas tanto como sea posible. .

Efecto de retención del cursor № 4

Subiré el nivel de dificultad para este último efecto, pero sabes lo suficiente de los otros ejemplos que dudo que tengas problemas con este.

Este efecto de rotación se basa en dos gradientes cónicos y más cálculos.

Inicialmente, tenemos ambos gradientes de dimensión cero en el Paso 1. Aumentamos el tamaño de cada uno del Paso 2. Continuamos aumentando sus anchos hasta que cubran completamente el elemento, como se muestra en el Paso 3. Luego los arrastramos hacia abajo para actualizar su posición. Esta es la parte «mágica» del efecto de retención del cursor. Dado que ambos degradados usarán el mismo color, cambiar su posición en el paso 4 no hará una diferencia visual, pero veremos una diferencia después de reducir el tamaño al mostrar el mouse durante el paso 5.

Si comparas los pasos 2 y 5, puedes ver que tenemos una pendiente diferente. Vamos a traducirlo a código:

.hover-4 {
  background-image:
    conic-gradient(/* ??? */),
    conic-gradient(/* ??? */);
  background-position:
    0 0,
    100% 0;
  background-size: 0% 200%;
  background-repeat: no-repeat;
  transition: background-size .4s, background-position 0s;
}
.hover-4:hover {
  background-size: /* ??? */ 200%;
  background-position:
    0 100%,
    100% 100%;
}

Las posiciones son bastante claras. Un gradiente comienza en la parte superior izquierda (0 0) y termina en la parte inferior izquierda0 100%), mientras que el otro comienza en la parte superior derecha100% 0) y termina en la parte inferior derecha100% 100%).

usamos un transition de posiciones de fondo y tamaños para revelarlos. Sólo necesitamos un valor de transición para background-size.Y como antes, background-position debe cambiarse inmediatamente, por lo que le asignamos un 0s valor para la duración de la transición.

Para las dimensiones, ambos gradientes deben tener 0 de ancho y el doble de la altura del elemento (0% 200%). Veremos más adelante cómo cambia su tamaño cuando mantienes presionado el mouse. Primero definamos la configuración del gradiente.

El siguiente diagrama ilustra la configuración de cada gradiente:

Tenga en cuenta que para el segundo degradado (marcado en verde) necesitamos saber la altura para usarlo dentro conic-gradient Nosotros creamos. Por eso añadiré un line-height que establece la altura del elemento y luego intenta el mismo valor para los valores del gradiente cónico que nos perdimos.

.hover-4 {
  --c: #1095c1;
  line-height: 1.2em;
  background-image:
    conic-gradient(from -135deg at 100%  50%, var(--c) 90deg, #0000 0),
    conic-gradient(from -135deg at 1.2em 50%, #0000 90deg, var(--c) 0);
  background-position:
    0 0,
    100% 0;
  background-size: 0% 200%;
  background-repeat: no-repeat;
  transition: background-size .4s, background-position 0s;
}
.hover-4:hover {
  background-size: /* ??? */ 200%;
  background-position:
    0 100%,
    100% 100%;
}

Lo último que debemos hacer es entender el tamaño del fondo, intuitivamente podemos pensar que cada degradado debería ocupar la mitad del ancho del elemento, pero en realidad esto no es suficiente.

Nos quedamos con una gran diferencia si usamos 50% como background-size valor para ambos gradientes.

Obtenemos un espacio igual a la altura, por lo que en realidad tenemos que aumentar el tamaño de cada gradiente en la mitad de la altura mientras mantiene presionado el cursor para cubrir todo el elemento.

.hover-4:hover {
  background-size: calc(50% + .6em) 200%;
  background-position:
    0 100%,
    100% 100%;
}

Esto es lo que obtenemos después de optimizarlos como en los ejemplos anteriores:

.hover-4 {
  --c: #1095c1;
  line-height: 1.2em;
  background:
    conic-gradient(from -135deg at 100%  50%, var(--c) 90deg, #0000 0) 
      0  var(--p, 0%) / var(--s, 0%) 200% no-repeat,
    conic-gradient(from -135deg at 1.2em 50%, #0000 90deg, var(--c) 0) 
      100% var(--p, 0%) / var(--s, 0%) 200% no-repeat;
  transition: .4s, background-position 0s;
}
.hover-4:hover {
  --p: 100%;
  --s: calc(50% + .6em);
}

¿Qué tal una versión con una sola característica personalizada?

les dejo esto! Después de observar cuatro efectos de retención de cursor similares, debería poder reducir la optimización final a una propiedad personalizada. ¡Comparte tu trabajo en la sección de comentarios! No hay recompensa, pero podemos obtener diferentes conversiones e ideas que son útiles para ¡todos!

Antes de terminar, compartamos una versión del último efecto de retención del cursor ana tudor cocido. ¡Esto es una mejora! Pero tenga en cuenta que no hay soporte para Firefox debido a un error. Sin embargo, esta es una gran idea que muestra cómo combinar degradados con modos de fusión para crear efectos aún más geniales mientras sostiene el mouse.

resumiendo

¡Hicimos cuatro efectos giratorios geniales! Y aunque hay diferentes efectos, todos usan el mismo enfoque para usar CSS background propiedades, propiedades personalizadas y calc()Diferentes combinaciones nos han permitido hacer diferentes versiones, todas usando las mismas técnicas que nos dejan un código limpio y manejable.

Si quieres tener algunas ideas, lo hice colección de 500 (¡sí, 500!) efectos de retención, 400 de los cuales están hechos sin pseudo-elementos. ¡Los cuatro que revisamos en este artículo son solo la punta del iceberg!

Deja una respuesta

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

Botón volver arriba