Decoraciones de imágenes de lujo: elemento único Magic PlatoBlockchain Data Intelligence. Búsqueda vertical. Ai.

Decoraciones de imágenes elegantes: Magia de un solo elemento

Como dice el título, ¡vamos a decorar imágenes! Hay muchos otros artículos que hablan de esto, pero lo que estamos cubriendo aquí es un poco diferente porque es más un desafío. ¿El reto? Decora una imagen usando solo el etiqueta y nada más.

Así es, sin marcado adicional, sin divs y sin pseudo-elementos. Solo una etiqueta.

Suena difícil, ¿verdad? Pero al final de este artículo, y de los demás que componen esta pequeña serie, demostraré que CSS es lo suficientemente poderoso como para brindarnos resultados excelentes y sorprendentes a pesar de la limitación de trabajar con un solo elemento.

Serie de decoraciones de imágenes de lujo

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

Comencemos con nuestro primer ejemplo.

Antes de profundizar en el código, enumeremos las posibilidades para diseñar un sin ningún elemento adicional o pseudo-elemento. Nosotros podemos usar border, box-shadow, outline, Y, por supuesto, background. Puede parecer extraño agregar un fondo a una imagen porque no podemos verlo porque estará detrás de la imagen, pero el truco es crear espacio. en torno a la imagen usando padding y/o border y luego dibujar nuestro fondo dentro de ese espacio.

Creo que sabes lo que viene después ya que hablé de background, ¿Correcto? Sí, gradientes! Todas las decoraciones que vamos a hacer se basan en muchos degradados. si tienes Sigueme por un tiempo, creo que esto probablemente no te sorprenda en absoluto. 😁

Volvamos a nuestro primer ejemplo:

img {
  --s: 10px; /* control the size */
  padding: var(--s);
  border: calc(2 * var(--s)) solid #0000;
  outline: 1px solid #000;
  outline-offset: calc(-1 * var(--s));
  background: conic-gradient(from 90deg at 1px 1px, #0000 25%, #000 0);
}

estamos definiendo padding y un transparente border usando la variable --s para crear un espacio alrededor de nuestra imagen igual a tres veces esa variable.

¿Por qué estamos usando ambos? padding y border en lugar de uno o el otro? Podemos obtener usando solo uno de ellos, pero necesito esta combinación para mi gradiente porque, por defecto, el valor inicial de background-clip is border-box y background-origin es igual a padding-box.

Aquí hay una ilustración paso a paso para entender la lógica:

Inicialmente, no tenemos bordes en la imagen, por lo que nuestro degradado creará dos segmentos con 1px de espesor (Estoy usando 3px en esta demostración específica para que sea más fácil de ver). Agregamos un borde coloreado y el degradado aún nos da el mismo resultado dentro del área de relleno (debido a background-origin) pero se repite detrás del borde. Si hacemos que el color del borde sea transparente, podemos usar la repetición y obtenemos el marco que queremos.

El outline en la demostración tiene un desplazamiento negativo. Eso crea una forma cuadrada en la parte superior del degradado. ¡Eso es todo! Agregamos una linda decoración a nuestra imagen usando un degradado y un outline. ¡Podríamos haber usado más gradientes! Pero siempre trato de mantener mi código lo más simple posible y descubrí que agregar un outline es mejor así.

Aquí hay una solución de solo gradiente donde estoy usando solo padding para definir el espacio. Sigue siendo el mismo resultado pero con una sintaxis más compleja.

Probemos con otra idea:

Para este, tomé el ejemplo anterior eliminé el outline, y aplicó un clip-path para cortar el degradado en cada lado. los clip-path value es un poco detallado y confuso, pero aquí hay una ilustración para ver mejor sus puntos:

Decoraciones de imágenes elegantes: Magia de un solo elemento

Creo que captas la idea principal. Vamos a combinar fondos, contornos, recortes y algunas máscaras para lograr diferentes tipos de decoraciones. ¡También vamos a considerar algunas animaciones geniales como una ventaja adicional! ¡Lo que hemos visto hasta ahora es simplemente una pequeña descripción general de lo que viene!

El marco de solo esquina

Este toma cuatro gradientes. Cada degradado cubre una esquina y, al pasar el mouse, los expandimos para crear un marco completo alrededor de la imagen. Analicemos el código de uno de los gradientes:

--b: 5px; /* border thickness */
background: conic-gradient(from 90deg at top var(--b) left var(--b), #0000 90deg, darkblue 0) 0 0;
background-size: 50px 50px; 
background-repeat: no-repeat;

Vamos a dibujar un degradado con un tamaño igual a 50px 50px y colóquelo en la esquina superior izquierda (0 0). Para la configuración del gradiente, aquí hay una ilustración paso a paso que muestra cómo llegué a ese resultado.

Tendemos a pensar que los gradientes solo son buenos para la transición entre dos colores. Pero en realidad, ¡podemos hacer mucho más con ellos! Son especialmente útiles a la hora de crear diferentes formas. El truco es asegurarse de que tengamos paradas duras entre los colores, como en el ejemplo anterior, en lugar de transiciones suaves:

#0000 25%, darkblue 0

Esto es básicamente decir: "llene el degradado con un color transparente hasta que 25% del área, luego llene el área restante con darkblue.

Podrías estar rascándote la cabeza sobre el 0 valor. Es un pequeño truco para simplificar la sintaxis. En realidad, deberíamos usar esto para hacer una parada brusca entre colores:

#0000 25%, darkblue 25%

¡Eso es más lógico! El color transparente termina en 25% y darkblue comienza exactamente donde termina la transparencia, haciendo una parada brusca. Si reemplazamos el segundo con 0, el navegador hará el trabajo por nosotros, por lo que es una forma un poco más eficiente de hacerlo.

En algún lugar de la especificación, dice:

si un parada de color or sugerencia de transición tiene una posición que es menor que la posición especificada de cualquier parada de color o sugerencia de transición anterior en la lista, establezca su posición para que sea igual a la posición especificada más grande de cualquier parada de color o sugerencia de transición anterior.

0 siempre es más pequeño que cualquier otro valor, por lo que el navegador siempre lo convertirá al valor más grande que viene antes que él en la declaración. En nuestro caso, ese número es 25%.

Ahora, aplicamos la misma lógica a todas las esquinas y terminamos con el siguiente código:

img {
  --b: 5px; /* border thickness */
  --c: #0000 90deg, darkblue 0; /* define the color here */
  padding: 10px;
  background:
    conic-gradient(from 90deg  at top    var(--b) left  var(--b), var(--c)) 0 0,
    conic-gradient(from 180deg at top    var(--b) right var(--b), var(--c)) 100% 0,
    conic-gradient(from 0deg   at bottom var(--b) left  var(--b), var(--c)) 0 100%,
    conic-gradient(from -90deg at bottom var(--b) right var(--b), var(--c)) 100% 100%;
  background-size: 50px 50px; /* adjust border length here */
  background-repeat: no-repeat;
}

He introducido variables CSS para evitar cierta redundancia ya que todos los degradados usan la misma configuración de color.

Para el efecto de desplazamiento, todo lo que estoy haciendo es aumentar el tamaño de los degradados para crear el cuadro completo:

img:hover {
  background-size: 51% 51%;
}

Sí, es 51% en lugar de 50% — que crea una pequeña superposición y evita posibles lagunas.

Probemos otra idea usando la misma técnica:

Esta vez estamos usando solo dos degradados, pero con una animación más compleja. Primero, actualizamos la posición de cada degradado, luego aumentamos sus tamaños para crear el cuadro completo. También introduje más variables para controlar mejor el color, el tamaño, el grosor e incluso el espacio entre la imagen y el marco.

img {
  --b: 8px;  /* border thickness*/
  --s: 60px; /* size of the corner*/
  --g: 14px; /* the gap*/
  --c: #EDC951; 

  padding: calc(var(--b) + var(--g));
  background-image:
    conic-gradient(from  90deg at top    var(--b) left  var(--b), #0000 25%, var(--c) 0),
    conic-gradient(from -90deg at bottom var(--b) right var(--b), #0000 25%, var(--c) 0);
  background-position:
    var(--_p, 0%) var(--_p, 0%),
    calc(100% - var(--_p, 0%)) calc(100% - var(--_p, 0%));
  background-size: var(--s) var(--s);
  background-repeat: no-repeat;
  transition: 
    background-position .3s var(--_i,.3s), 
    background-size .3s calc(.3s - var(--_i, .3s));
}
img:hover {
  background-size: calc(100% - var(--g)) calc(100% - var(--g));
  --_p: calc(var(--g) / 2);
  --_i: 0s;
}

¿Por qué el --_i y --_p variables tienen un guión bajo en su nombre? Los guiones bajos son parte de una convención de nomenclatura que utilizo para considerar las variables "internas" utilizadas para optimizar el código. No son nada especial, pero quiero marcar la diferencia entre las variables que ajustamos para controlar el marco (como --b, --c, etc.) y los que uso para acortar el código.

El código puede parecer confuso y no fácil de comprender, pero escribí un serie de tres partes donde detallo tal técnica. Recomiendo encarecidamente leer al menos el primer artículo para comprender cómo llegué al código anterior.

Aquí hay una ilustración para entender mejor los diferentes valores:

Mostrando la misma imagen de dos autos clásicos tres veces para ilustrar las variables CSS utilizadas en el código.
Decoraciones de imágenes elegantes: Magia de un solo elemento

La revelación del marco

Probemos con otro tipo de animación donde revelamos el cuadro completo al pasar el mouse:

¿Guay, verdad? Y si miras de cerca, notarás que las líneas desaparecen en la dirección opuesta al pasar el mouse, ¡lo que hace que el efecto sea aún más elegante! Usé un efecto similar en un artículo anterior.

Pero esta vez, en lugar de cubrir todo el elemento, cubro solo una pequeña parte definiendo un height para obtener algo como esto:

Este es el borde superior de nuestro marco. Repetimos el mismo proceso en cada lado de la imagen y tenemos nuestro efecto de desplazamiento:

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

  padding: calc(var(--g) + var(--b));
  --_g: no-repeat linear-gradient(var(--c) 0 0);
  background: 
    var(--_g) var(--_i, 0%) 0,
    var(--_g) 100% var(--_i, 0%),
    var(--_g) calc(100% - var(--_i, 0%)) 100%,
    var(--_g) 0 calc(100% - var(--_i, 0%));
  background-size: var(--_i, 0%) var(--b),var(--b) var(--_i, 0%);
  transition: .4s, background-position 0s;
  cursor: pointer;
}
img:hover {
  --_i: 100%;
}

Como puede ver, estoy aplicando el mismo degradado cuatro veces y cada uno tiene una posición diferente para cubrir solo un lado a la vez.

¿Otro? ¡Vamos!

Este parece un poco complicado y, de hecho, requiere algo de imaginación para comprender cómo dos gradientes cónicos están logrando este tipo de magia. Aquí hay una demostración para ilustrar uno de los gradientes:

El pseudo-elemento simula el degradado. Inicialmente está fuera de la vista y, al pasar el mouse, primero cambiamos su posición para obtener el borde superior del marco. Luego aumentamos la altura para obtener el borde correcto. La forma del degradado es similar a las que usamos en la última sección: dos segmentos para cubrir dos lados.

Pero, ¿por qué hice el ancho del degradado? 200%? pensarías 100% sería suficiente, ¿verdad?

100% debería ser suficiente, pero no podré mover el gradiente como quiero si mantengo su ancho igual a 100%. Esa es otra pequeña peculiaridad relacionada con cómo background-position obras. Cubro esto en un artículo anterior. Yo también publicó una respuesta en Stack Overflow lidiando con esto. Sé que es mucha lectura, pero realmente vale la pena su tiempo.

Ahora que hemos explicado la lógica de un degradado, el segundo es fácil porque hace exactamente lo mismo, pero cubre los bordes izquierdo e inferior. Todo lo que tenemos que hacer es intercambiar algunos valores y listo:

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

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

Como puede ver, ambos gradientes son casi idénticos. Simplemente estoy intercambiando los valores de tamaño y posición.

La rotación del marco

Esta vez no vamos a dibujar un marco alrededor de nuestra imagen, sino a ajustar el aspecto de una existente.

Probablemente te estés preguntando cómo diablos puedo transformar una línea recta en una línea en ángulo. No, la magia es diferente a eso. Esa es solo la ilusión que obtenemos después de combinar animaciones simples para cuatro gradientes.

Veamos cómo se hace la animación para el degradado superior:

Simplemente estoy actualizando la posición de un gradiente repetitivo. ¡Nada elegante todavía! Hagamos lo mismo para el lado derecho:

¿Estás empezando a ver el truco? Ambos degradados se cruzan en la esquina para crear la ilusión de que la línea recta cambia a una en ángulo. Eliminemos el contorno y ocultemos el desbordamiento para verlo mejor:

Ahora, agregamos dos degradados más para cubrir los bordes restantes y listo:

img {
  --g: 4px; /* the gap */
  --b: 12px; /* border thickness*/
  --c: #669706; /* the color */

  padding: calc(var(--g) + var(--b));
  --_c: #0000 0 25%, var(--c) 0 50%;
  --_g1: repeating-linear-gradient(90deg ,var(--_c)) repeat-x;
  --_g2: repeating-linear-gradient(180deg,var(--_c)) repeat-y;
  background:
    var(--_g1) var(--_p, 25%) 0, 
    var(--_g2) 0 var(--_p, 125%),
    var(--_g1) var(--_p, 125%) 100%, 
    var(--_g2) 100% var(--_p, 25%);
  background-size: 200% var(--b), var(--b) 200%;
  transition: .3s;
}
img:hover {
  --_p: 75%;
}

Si tomamos este código y lo ajustamos ligeramente, podemos obtener otra animación genial:

¿Puedes descifrar la lógica en este ejemplo? ¡Esa es tu tarea! El código puede parecer aterrador, pero usa la misma lógica que los ejemplos anteriores que vimos. Intenta aislar cada degradado e imagina cómo se anima.

Terminando

¡Eso es un montón de gradientes en un artículo!

¡Seguro que lo es y te lo advertí! Pero si el reto es decorar una imagen sin elementos extra y pseudo-elementos, nos quedan pocas posibilidades y los degradados son la opción más potente.

No te preocupes si te pierdes un poco en alguna de las explicaciones. Siempre recomiendo algunos de mis artículos antiguos donde detallo más algunos de los conceptos que reciclamos para este reto.

Me iré con una última demostración para esperar hasta el próximo artículo de esta serie. Esta vez, estoy usando radial-gradient() para crear otro divertido efecto de desplazamiento. Te dejaré diseccionar el código para asimilar cómo funciona. ¡Hazme preguntas en los comentarios si te quedas atascado!

Serie de decoraciones de imágenes de lujo

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

Sello de tiempo:

Mas de Trucos CSS