Examiner plusieurs façons d'animer une bordure en CSS
Définir des bordures
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.
Un article qui a récemment attiré mon attention est Fantastic CSS border animation (Animation de bordure CSS fantastique), dans lequel l'auteur Coco explore 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é.
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. Pour créer une bordure, les images d'arrière-plan définies sont répétées dans la bordure elle-même, ce qui donne cet effet visuel étrange.
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
.
/* 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%);
background-origin: border-box;
Cette seule modification améliore considérablement l'affichage:
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
. L'arrière-plan n'est donc plus dessiné sous la zone de la bordure.
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, cela devient un jeu d'enfant dans les navigateurs compatibles:
@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
.
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
;
Toutefois, vous remarquerez que certaines choses ne fonctionnent plus avec cette approche:
- Le
border-image
ne suit pas leborder-radius
. Il reste toujours rectangulaire. - Lorsque vous définissez
border-image-slice
sur "fill" (Remplissage), leborder-image
n'est pas peint sous l'background
défini, 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.