Animations de bordure CSS

Examiner plusieurs façons d'animer une bordure en CSS

Plusieurs méthodes sont disponibles pour définir une bordure sur un élément : border, outline et box-shadow. Comme détaillé dans The 3 CSS Methods for Adding Element Borders (Les trois méthodes CSS pour ajouter des bordures d'éléments) de Stephanie Eckles, chaque approche présente ses propres avantages et inconvénients, en particulier en ce qui concerne l'animation des bordures. La principale raison de ne pas utiliser un border CSS approprié est l'animation.

Animations de bordure avec outline-offset de Kevin J. Powell

Un article qui a récemment attiré mon attention s'intitule Fantastic CSS border animation (Animation de bordure CSS fantastique), dans lequel l'auteur Coco a exploré d'autres options. En injectant du contenu généré à l'aide de ::before et ::after, ils créent une fausse bordure qui est ensuite animée.

Ce qui me frappe le plus, ce sont les visualisations animées utilisées dans l'article. Ils aident vraiment à expliquer ce qui est fait exactement pour obtenir l'effet souhaité.

Animations de bordure à l'aide de contenu généré par Coco

La couche blanche et les lignes colorées sont des contenus générés. En faisant apparaître et disparaître la couche blanche, vous pouvez voir clairement comment les éléments sont empilés et comment l'animation fonctionne.

Conserver le modèle de boîte

L'inconvénient d'utiliser du contenu généré pour imiter une bordure est que vous obtenez un modèle de boîte défectueux : le contenu peut désormais masquer la fausse bordure, car cette "bordure" est peinte en dessous. Pour atténuer ce problème, vous devez appliquer le border-width souhaité en tant que padding.

Pour obtenir une véritable bordure et conserver le fonctionnement du modèle de boîte, vous pouvez utiliser plusieurs arrière-plans que vous étirez ensuite dans la zone de bordure.

Principes de base

Commençons par créer une bordure en pointillés et ajoutons plusieurs arrière-plans.

/* 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
  )
;

Redimensionner les arrière-plans avec background-origin

Comme vous pouvez le voir, il se passe quelque chose d'étrange avec les arrière-plans : ils sont peints dans la bordure, mais le conic-gradient semble tout à fait incorrect. Il s'agit d'un comportement prévu : par défaut, les images de fond ne sont pas dessinées dans la bordure, car leur origine est le padding-box de l'élément. Après tout, pour créer une bordure, les images de fond définies sont répétées dans la bordure elle-même, ce qui génère un effet visuel inhabituel.

Pour résoudre ce problème, vous devez étirer l'arrière-plan afin qu'il occupe également la taille de la bordure. Vous pouvez le faire manuellement en étirant et en repositionnant l'arrière-plan, mais il est préférable d'utiliser la propriété background-origin pour dimensionner l'arrière-plan par rapport à border-box.

Navigateurs pris en charge

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

Source

À éviter
/* 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%);
À faire
background-origin: border-box;

Cette seule modification rend tout beaucoup plus clair :

Réduire la taille du calque d'arrière-plan blanc avec background-clip

Les arrière-plans occupant désormais tout l'espace, la couche semi-transparente doit être réduite à nouveau. Au lieu de vous embêter à nouveau avec background-size, il existe une méthode plus simple : utilisez background-clip et définissez-le sur padding-box. De cette façon, l'arrière-plan n'est plus dessiné sous la zone de la bordure.

Navigateurs pris en charge

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

Source

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

Enfin, définissez la bordure sur transparent pour obtenir l'effet complet.

border: 0.3rem dotted transparent;

Animation

Pour restaurer l'animation de la bordure, vous pouvez modifier l'angle de début de conic-gradient.

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

Grâce à @property, l'opération devient un jeu d'enfant dans les navigateurs compatibles:

Navigateurs pris en charge

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

Source

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

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

Le code combiné se présente comme suit :

Contenu supplémentaire : border-image

Une approche déjà abordée pour dessiner une bordure dégradée consiste à utiliser CSS border-image.

Navigateurs pris en charge

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

Source

Cela permet de simplifier le code, car vous n'avez pas à gérer les arrière-plans qui se chevauchent. Vous pouvez appliquer l'animation de la même manière qu'auparavant.

/* 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
;

Cependant, vous remarquerez que certains éléments ne fonctionnent plus avec cette approche:

  • Le border-image ne suit pas le border-radius. Il reste toujours rectangulaire.
  • Lorsque vous définissez border-image-slice pour remplir, le border-image n'est pas peint sous l'ensemble background, mais au-dessus. Cela peut être gênant si vous souhaitez que l'arrière-plan soit semi-transparent.

Pour conclure

Il existe de nombreuses possibilités d'animer les bordures en CSS. Selon le cas d'utilisation, vous pouvez privilégier l'une ou l'autre.