Logotipo de Zephyrnet

Decoraciones de imágenes elegantes: máscaras y efectos de desplazamiento avanzados

Fecha:

¡Bienvenido a la Parte 2 de esta serie de tres partes! Seguimos decorando imágenes sin ningún elemento adicional ni pseudoelemento. Espero que ya te hayas tomado el tiempo de digerir Parte 1 porque seguiremos trabajando con muchos degradados para crear efectos visuales impresionantes. También vamos a introducir el CSS mask propiedad para decoraciones más complejas y efectos de desplazamiento.

Serie de decoraciones de imágenes de lujo

  • Magia de un solo elemento
  • Máscaras y efectos de desplazamiento avanzados (¡estás aquí!)
  • Contornos y animaciones complejas (próximo 28 de octubre )

Pasemos al primer ejemplo en el que estamos trabajando juntos...

el sello postal

Lo creas o no, todo lo que se necesita para crear un efecto CSS de sello postal son dos gradientes y un filtro:

img {
  --r: 10px; /* control the radius of the circles */
  padding: calc(2 * var(--r));
  filter: grayscale(.4);
  background: 
    radial-gradient(var(--r),#0000 98%,#fff) round
      calc(-1.5 * var(--r)) calc(-1.5 * var(--r)) / calc(3 * var(--r)) calc(3 * var(--r)),
    linear-gradient(#fff 0 0) no-repeat
      50% / calc(100% - 3 * var(--r)) calc(100% - 3 * var(--r));
}

Como vimos en el articulo anterior, el primer paso es hacer espacio alrededor de la imagen con padding para que podamos dibujar un degradado de fondo y verlo allí. Entonces usamos una combinación de radial-gradient() y linear-gradient() para cortar esos círculos alrededor de la imagen.

Aquí hay una ilustración paso a paso que muestra cómo se configuran los gradientes:

Tenga en cuenta el uso de la round valor en el segundo paso. Es muy importante para el truco, ya que garantiza que el tamaño del degradado se ajuste para que esté perfectamente alineado en todos los lados, sin importar el ancho o el alto de la imagen.

Desde la especificación: La imagen se repite tantas veces como quepa dentro del área de posicionamiento de fondo. Si no cabe un número entero de veces, se vuelve a escalar para que sí.

El marco redondeado

Veamos otra decoración de imagen que usa círculos…

Este ejemplo también utiliza un radial-gradient(), pero esta vez he creado círculos en torno a la imagen en lugar del efecto de recorte. Tenga en cuenta que también estoy usando el round valor de nuevo. La parte más complicada aquí es el espacio transparente entre el marco y la imagen, que es donde alcanzo el CSS. mask propiedad:

img {
  --s: 20px; /* size of the frame */
  --g: 10px; /* the gap */
  --c: #FA6900; 

  padding: calc(var(--g) + var(--s));
  background: 
    radial-gradient(farthest-side, var(--c) 97%, #0000) 
      0 0 / calc(2 * var(--s)) calc(2 * var(--s)) round;
  mask:
    conic-gradient(from 90deg at calc(2 * var(--s)) calc(2 * var(--s)), #0000 25%, #000 0)
      calc(-1 * var(--s)) calc(-1 * var(--s)),
    linear-gradient(#000 0 0) content-box;
}

El enmascaramiento nos permite mostrar el área de la imagen, gracias a la linear-gradient() allí, así como 20px alrededor de cada lado de la misma, gracias a la conic-gradient(). 20px no es más que la variable --s que define el tamaño del marco. En otras palabras, necesitamos ocultar la brecha.

Esto es lo que quiero decir:

El degradado lineal es la parte azul del fondo, mientras que el degradado cónico es la parte roja del fondo. Esa parte transparente entre ambos degradados es lo que cortamos de nuestro elemento para crear la ilusión de un borde interior transparente.

El borde transparente interior

Para este, no vamos a crear un marco, sino a intentar algo diferente. Vamos a crear un borde interior transparente. dentro nuestra imagen Probablemente no sea tan útil en un escenario del mundo real, pero es una buena práctica con las máscaras CSS.

Al igual que en el ejemplo anterior, nos basaremos en dos gradientes: un linear-gradient() para la parte interior, y un conic-gradient() para la parte exterior. Dejaremos un espacio entre ellos para crear el efecto de borde transparente.

img {
  --b: 5px;  /* the border thickness */
  --d: 20px; /* the distance from the edge */

  --_g: calc(100% - 2 * (var(--d) + var(--b)));
  mask:
    conic-gradient(from 90deg at var(--d) var(--d), #0000 25%, #000 0)
      0 0 / calc(100% - var(--d)) calc(100% - var(--d)),
    linear-gradient(#000 0 0) 50% / var(--_g) var(--_g) no-repeat;
}

Es posible que haya notado que el gradiente cónico de este ejemplo tiene una sintaxis diferente a la del ejemplo anterior. Se supone que ambos crean la misma forma, entonces, ¿por qué son diferentes? Es porque podemos llegar al mismo resultado usando diferentes sintaxis. Esto puede parecer confuso al principio, pero es una buena característica. No estás obligado a encontrar las solución para lograr una forma particular. Solo necesita encontrar una solución que funcione para usted entre las muchas posibilidades que existen.

Aquí hay cuatro formas de crear el cuadrado exterior usando degradados:

Incluso hay más formas de lograr esto, pero entiendes el punto.

No existe un enfoque Best™. Personalmente, trato de encontrar el que tiene el código más pequeño y optimizado. Para mí, cualquier solución que requiera menos gradientes, menos cálculos y menos valores repetidos es la más adecuada. A veces elijo una sintaxis más detallada porque me da más flexibilidad para cambiar variables y modificar cosas. Viene con la experiencia y la práctica. Cuanto más juegues con los degradados, más sabrás qué sintaxis usar y cuándo.

Volvamos a nuestro borde transparente interior y profundicemos en el efecto de desplazamiento. En caso de que no lo hayas notado, hay un genial efecto de desplazamiento que mueve ese borde transparente usando un font-size truco. La idea es definir el --d variable con un valor de 1em. Esta variable controla la distancia del borde desde el borde. Podemos transformar así:

--_d: calc(var(--d) + var(--s) * 1em)

…dándonos el siguiente CSS actualizado:

img {
  --b: 5px;  /* the border thickness */
  --d: 20px; /* the distance from the edge */
  --o: 15px; /* the offset on hover */
  --s: 1;    /* the direction of the hover effect (+1 or -1)*/

  --_d: calc(var(--d) + var(--s) * 1em);
  --_g: calc(100% - 2 * (var(--_d) + var(--b)));
  mask:
    conic-gradient(from 90deg at var(--_d) var(--_d), #0000 25%, #000 0)
     0 0 / calc(100% - var(--_d)) calc(100% - var(--_d)),
    linear-gradient(#000 0 0) 50% / var(--_g) var(--_g) no-repeat;
  font-size: 0;
  transition: .35s;
}
img:hover {
  font-size: var(--o);
}

El font-size es inicialmente igual a 0 ,entonces 1em también es igual a 0 y --_d es ser igual a --d. Al pasar el mouse, sin embargo, el font-size es igual a un valor definido por un --o variable que establece el desplazamiento del borde. Esto, a su vez, actualiza la --_d variable, moviendo el borde por el desplazamiento. Luego agrego otra variable, --s, para controlar la señal que decide si el borde se mueve hacia el interior o hacia el exterior.

El font-size trick es realmente útil si queremos animar propiedades que de otro modo no se pueden animar. Propiedades personalizadas definidas con @property puede resolver esto pero apoyo para ello todavía falta en el momento en que escribo esto.

La revelación del marco

Hicimos la siguiente animación de revelación en la primera parte de esta serie:

Podemos tomar la misma idea, pero en lugar de un borde con un color sólido usaremos un degradado como este:

Si compara ambos códigos, notará los siguientes cambios:

  1. Usé la misma configuración de degradado del primer ejemplo dentro del mask propiedad. Simplemente moví los gradientes de la background propiedad a la mask propiedad.
  2. Agregué un repeating-linear-gradient() para crear el borde degradado.

¡Eso es todo! Reutilicé la mayor parte del mismo código que ya vimos, con ajustes muy pequeños, y obtuve otra decoración de imagen genial con un efecto de desplazamiento.

/* Solid color border */

img {
  --c: #8A9B0F; /* the border color */
  --b: 10px;   /* the border thickness*/
  --g: 5px;  /* the gap on hover */

  padding: calc(var(--g) + var(--b));
  --_g: #0000 25%, var(--c) 0;
  background: 
    conic-gradient(from 180deg at top var(--b) right var(--b), var(--_g))
     var(--_i, 200%) 0 / 200% var(--_i, var(--b)) no-repeat,
    conic-gradient(at bottom var(--b) left  var(--b), var(--_g))
     0 var(--_i, 200%) / var(--_i, var(--b)) 200% no-repeat;
  transition: .3s, background-position .3s .3s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
  transition: .3s, background-size .3s .3s;
}
/* Gradient color border */

img {
  --b: 10px; /* the border thickness*/
  --g: 5px;  /* the gap on hover */
  background: repeating-linear-gradient(135deg, #F8CA00 0 10px, #E97F02 0 20px, #BD1550 0 30px);

  padding: calc(var(--g) + var(--b));
  --_g: #0000 25%, #000 0;
  mask: 
    conic-gradient(from 180deg at top var(--b) right var(--b), var(--_g))
     var(--_i, 200%) 0 / 200% var(--_i, var(--b)) no-repeat,
    conic-gradient(at bottom var(--b) left  var(--b), var(--_g))
     0 var(--_i, 200%) / var(--_i, var(--b)) 200% no-repeat,
    linear-gradient(#000 0 0) content-box;
  transition: .3s, mask-position .3s .3s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
  transition: .3s, mask-size .3s .3s;
}

Probemos con otro cuadro de animación. Este es un poco complicado ya que tiene un animación de tres pasos:

El primer paso de la animación es agrandar el borde inferior. Para ello ajustamos el background-size menos linear-gradient():

Probablemente se esté preguntando por qué también estoy agregando el borde superior. Lo necesitamos para el tercer paso. Siempre trato de optimizar el código que escribo, así que estoy usando un degradado para cubrir los lados superior e inferior, pero el superior está oculto y revelado más tarde con un mask.

Para el segundo paso, agregamos un segundo degradado para mostrar los bordes izquierdo y derecho. Pero esta vez, lo hacemos usando background-position:

Podemos detenernos aquí porque ya tenemos un buen efecto con dos degradados, pero estamos aquí para superar los límites, así que agreguemos un toque de máscara para lograr el tercer paso.

El truco es ocultar el borde superior hasta que mostramos la parte inferior y los lados y luego actualizamos el mask-size (o mask-position) para mostrar la parte superior. Como dije anteriormente, podemos encontrar muchas configuraciones de degradado para lograr el mismo efecto.

Aquí hay una ilustración de los gradientes que usaré:

Estoy usando dos gradientes cónicos que tienen un ancho igual a 200%. Ambos degradados cubren el área dejando solo la parte superior descubierta (esa parte será invisible más adelante). Al pasar el mouse, deslizo ambos degradados para cubrir esa parte.

Aquí hay una mejor ilustración de uno de los gradientes para darle una mejor idea de lo que está sucediendo:

Ahora ponemos esto dentro del mask propiedad y hemos terminado! Aquí está el código completo:

img {
  --b: 6px;  /* the border thickness*/
  --g: 10px; /* the gap */
  --c: #0E8D94;

  padding: calc(var(--b) + var(--g));
  --_l: var(--c) var(--b), #0000 0 calc(100% - var(--b)), var(--c) 0;
  background:
    linear-gradient(var(--_l)) 50%/calc(100% - var(--_i,80%)) 100% no-repeat,
    linear-gradient(90deg, var(--_l)) 50% var(--_i,-100%)/100% 200% no-repeat;  
  mask:
    conic-gradient(at 50% var(--b),#0000 25%, #000 0) calc(50% + var(--_i, 50%)) / 200%,
    conic-gradient(at 50% var(--b),#000 75%, #0000 0) calc(50% - var(--_i, 50%)) / 200%;
  transition: 
    .3s calc(.6s - var(--_t,.6s)) mask-position, 
    .3s .3s background-position,
    .3s var(--_t,.6s) background-size,
    .4s transform;
  cursor: pointer;
}
img:hover {
  --_i: 0%;
  --_t: 0s;
  transform: scale(1.2);
}

También introduje algunas variables para optimizar el código, pero deberías estar acostumbrado a esto ahora.

¿Qué pasa con una animación de cuatro pasos? ¡Si es posible!

¡No hay explicación para esto porque es tu tarea! Tome todo lo que ha aprendido en este artículo para diseccionar el código e intente articular lo que está haciendo. La lógica es similar a todos los ejemplos anteriores. La clave es aislar cada degradado para comprender cada paso de la animación. Mantuve el código sin optimizar para que las cosas fueran un poco más fáciles de leer. Yo tengo una versión optimizada si está interesado, pero también puede intentar optimizar el código usted mismo y compararlo con mi versión para practicar más.

Terminando

Eso es todo para la Parte 2 de esta serie de tres partes sobre decoraciones de imágenes creativas usando solo el elemento. Ahora tenemos una buena idea de cómo se pueden combinar los degradados y las máscaras para crear impresionantes efectos visuales e incluso animaciones, sin buscar elementos adicionales o pseudoelementos. si, un solo etiqueta es suficiente!

Tenemos un artículo más en esta serie para ir. Hasta entonces, aquí hay una demostración adicional con un efecto de desplazamiento genial donde uso mask para montar una imagen rota.

Serie de decoraciones de imágenes de lujo

  • Magia de un solo elemento
  • Máscaras y efectos de desplazamiento avanzados (¡estás aquí!)
  • Contornos y animaciones complejas (próximo 28 de octubre )
punto_img

Información más reciente

punto_img