Animaciones de bordes CSS

Cómo analizar varias formas de animar un borde en CSS

Hay algunos métodos disponibles para establecer un borde en un elemento: border, outline y box-shadow. Como se detalla en The 3 CSS Methods for Adding Element Borders de Stephanie Eckles, cada enfoque tiene sus propias ventajas y desventajas, en especial cuando se trata de animar los bordes. El motivo principal para no usar un border de CSS adecuado es para la animación.

Animaciones de borde con outline-offset de Kevin J. Powell

Un artículo que me llamó la atención recientemente es Fantastic CSS border animation, en el que la autora Coco exploró más opciones. Cuando se inyecta contenido generado con ::before y ::after, se crea un borde falso que luego se anima.

Lo que más me llama la atención son las visualizaciones animadas de respaldo que se usan en el artículo. Ayudan a explicar exactamente qué se está haciendo para lograr el efecto deseado.

Animaciones de borde con contenido generado por Coco

Tanto la capa blanca como las líneas de colores son contenido generado. Cuando se atenúa la capa blanca, se aclara cómo se apilan y cómo funciona la animación.

Retención del modelo de cuadro

Una desventaja de usar contenido generado para imitar un borde es que terminas con un modelo de cuadro roto: el contenido ahora puede ocultar el borde falso porque ese "borde" se pinta debajo. Para mitigarlo, debes aplicar el border-width deseado como padding.

Para tener un borde real y, así, conservar el funcionamiento del modelo de cuadro, puedes usar varios fondos que luego estirarás en el área del borde.

Conceptos básicos

Comencemos por crear un borde con puntos y agregar los múltiples fondos.

/* Size of the border */
--border-size: 0.5rem;

/* Create a dotted border */
border: var(--border-size) dotted lime;

/* Create two background layers:
   1. A white semi-transparent
   2. A layer with the colored boxes
 */

background-image:
  linear-gradient
(to right, rgb(255 255 255 / 0.5), rgb(255 255 255 / 0.5)),

  conic-gradient
(
    from
45deg,
   
#d53e33 0deg 90deg,
   
#fbb300 90deg 180deg,
   
#377af5 180deg 270deg,
   
#399953 270deg 360deg
 
)
;

Cómo cambiar el tamaño de los fondos con background-origin

Como puedes ver, hay algo extraño con los fondos: están pintados en el borde, pero el conic-gradient parece estar todo mal. En realidad, este es el comportamiento previsto: de forma predeterminada, las imágenes de fondo no se dibujan en el borde, ya que su origen es el padding-box del elemento. Después de todo, para crear un borde, las imágenes de fondo establecidas se repiten en el borde, lo que genera un efecto visual extraño.

Para resolver este problema, debes estirar el fondo para que también ocupe el tamaño del borde. Puedes hacerlo de forma manual estirando y cambiando la posición del fondo, pero lo mejor es usar la propiedad background-origin para ajustar el tamaño del fondo en relación con border-box.

Navegadores compatibles

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 3.

Origen

Qué no debes hacer
/* Manually add or offset the size of the border where needed */
background-position: calc(var(--border-size) * -1) calc(var(--border-size) * -1);
background-size: calc(var(--border-size) * 2 + 100%) calc(var(--border-size) * 2 + 100%);
Qué debes hacer
background-origin: border-box;

Este solo agregado hace que todo se vea mucho mejor:

Reducción de la capa de fondo blanco con background-clip

Ahora que los fondos ocupan todo el espacio, la capa semitransparente debe volver a reducirse. En lugar de volver a jugar con background-size, hay una forma más fácil de hacerlo: usa background-clip y configúralo en padding-box. De esta manera, el fondo ya no se dibuja debajo del área del borde.

Navegadores compatibles

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 5.

Origen

background-clip:
  padding-box
, /* Clip white semi-transparent to the padding-box */
  border-box
/* Clip colored boxes to the border-box (default) */
;

Por último, establece el borde transparent para que tenga el efecto completo.

border: 0.3rem dotted transparent;

Animación

Para restablecer la animación del borde, puedes manipular el ángulo de inicio de conic-gradient.

--angle: 0deg;
conic-gradient
(
  from var
(--angle),
 
#d53e33 0deg 90deg,
 
#fbb300 90deg 180deg,
 
#377af5 180deg 270deg,
 
#399953 270deg 360deg
);

Gracias a @property, esto se vuelve muy sencillo en los navegadores que lo admiten:

Navegadores compatibles

  • Chrome: 85.
  • Edge: 85.
  • Firefox: 128.
  • Safari: 16.4.

Origen

@property --angle {
 
syntax: "<angle>";
 
initial-value: 0deg;
 
inherits: false;
}

@keyframes rotate {
  to
{
   
--angle: 360deg;
 
}
}

Todo junto, el código se convierte en lo siguiente:

Contenido adicional: border-image

Un enfoque que ya se analizó para dibujar un borde de gradiente es usar CSS border-image.

Navegadores compatibles

  • Chrome: 16.
  • Edge: 12.
  • Firefox: 15.
  • Safari: 6.

Origen

Permite un código más simplificado, ya que no necesitas lidiar con fondos superpuestos. La animación se puede aplicar de la misma manera que antes.

/* Create a border */
border: 0.5rem solid transparent;

/* Paint an image in the border */
border-image:
  conic-gradient
(
    from var
(--angle),
   
#d53e33 0deg 90deg,
   
#fbb300 90deg 180deg,
   
#377af5 180deg 270deg,
   
#399953 270deg 360deg
 
) 1
;

Sin embargo, notarás que algunos elementos ya no funcionan con este enfoque:

  • El border-image no sigue el border-radius; siempre será rectangular.
  • Cuando se establece border-image-slice para que se llene, el border-image no se pinta debajo del conjunto background, sino en la parte superior. Esto puede ser problemático si quieres que el fondo sea semitransparente.

Para finalizar

Hay una gran cantidad de posibilidades para animar bordes en CSS. Según el caso de uso, puedes usar uno o el otro.