Que voulez-vous savoir ?
Comparer deux billets de trainRésumer un PDFPréparer un week-end
Bordure arc-en-ciel en dégradé conique qui fait le tour de la boîte en 3 s, puis en 1 s avec un halo flou au survol, au focus ou au toucher.
Mis à jour le
Cet effet est gratuit — la catégorie Utilitaires en contient 43 au total, dont 3 gratuits. Effect.Labs regroupe 840 effets vanilla. Découvrir la catégorie →
Comparer deux billets de trainRésumer un PDFPréparer un week-end
Chaînes suivies · 2 en direct
Concours de la librairie · 6 participants
Gagnant :
Derrière la boîte .gsp-box (200 × 120 px, arrondi 12 px), le pseudo-élément ::before dépasse de 3 px de chaque côté et se remplit d'un conic-gradient rose #ff0080, orange #ff8c00, turquoise #40e0d0, violet #7b2ff7, puis de nouveau rose pour fermer le cercle. Le pseudo-élément ::after, de la couleur du fond, recouvre l'intérieur à 3 px du bord : il reste une bande colorée de 6 px, à moitié dehors, à moitié dedans.
Le dégradé part d'un angle --gsp-angle déclaré avec @property comme un vrai <angle>, que l'animation gspSpin fait passer de 0 à 360° en 3 s, en continu et à vitesse constante. Au survol, ou quand un élément de la boîte a le focus (:focus-within), la durée passe à 1 s et un flou de 4 px transforme la bande en halo. Changer la durée d'une animation en cours la recale : au moment où l'on entre ou sort, les couleurs sautent d'un coup à un autre angle avant de reprendre leur rotation.
Le libellé est un lien, .gsp-link, dont le ::after couvre toute la boîte : un clic n'importe où suit le lien, et c'est ce lien qui rend l'effet atteignable au clavier et au doigt. Remplacez son href="#gradient-spin" par votre adresse et son texte par le vôtre. Le rayon est réglable (--gsp-radius) : la bande et le masque intérieur le suivent, jusqu'à la pilule ou au cercle.
--gsp-ring) apparaît 4 px au-delà de la bande quand le focus vient du clavier. Avec un champ dans la boîte, comme dans l'exemple de l'assistant, c'est la saisie qui déclenche l'accélération. Dans Safari, Tab ne passe sur les liens que si le réglage clavier du navigateur le prévoit (Option+Tab sinon).prefers-reduced-motion: reduce, la rotation s'arrête, le dégradé reste affiché (rose en haut), et le halo flou apparaît toujours au survol et au focus.CSS seul, aucun JavaScript. Mesuré dans Chromium 151, Firefox 153 et le WebKit 26.5 de Playwright : rotation, accélération et halo au survol, Tab, toucher, deux copies indépendantes, 390 px, et plus aucune animation infinie en mouvement réduit. Versions minimales d'après @mdn/browser-compat-data : la rotation demande @property (Chrome 85, Firefox 128, Safari 16.4) ; le lien étiré utilise inset (Chrome 87).
Sans @property, l'angle prend la valeur de secours écrite dans var(--gsp-angle, 0deg) : la bordure arc-en-ciel s'affiche, immobile, et le halo flou fonctionne toujours (vérifié en retirant la règle @property dans Chromium).
Copiez les deux blocs (HTML et CSS) dans votre page. Aucun JavaScript, aucune dépendance.
<div class="fx-0765-root">
<div class="gsp-box">
<a class="gsp-link" href="#gradient-spin">Gradient Spin</a>
</div>
</div>
.fx-0765-root,
.fx-0765-root *,
.fx-0765-root *::before,
.fx-0765-root *::after {
box-sizing: border-box
}
.fx-0765-root {
--gsp-w: 200px; /* box width */
--gsp-h: 120px; /* box height */
--gsp-radius: 12px; /* box corner radius (the border follows) */
--gsp-width: 3px; /* border thickness */
--gsp-colors: #ff0080, #ff8c00, #40e0d0, #7b2ff7, #ff0080;
--gsp-speed: 3s; /* one turn at rest */
--gsp-speed-hover: 1s; /* one turn on hover, focus, tap */
--gsp-halo: 4px; /* halo blur on hover */
--gsp-fill: #0a0a0f; /* box fill */
--gsp-ring: #fff; /* keyboard focus ring */
display: flex;
align-items: center;
justify-content: center;
width: 100%;
position: relative;
font-family: sans-serif;
}
@property --gsp-angle {
syntax: '<angle>';
initial-value: 0deg;
inherits: false;
}
.fx-0765-root .gsp-box {
width: var(--gsp-w);
max-width: 100%;
height: var(--gsp-h);
display: flex;
align-items: center;
justify-content: center;
font-size: 0.95rem;
font-weight: 600;
color: white;
border-radius: var(--gsp-radius);
position: relative;
font-family: inherit;
user-select: none;
background: var(--gsp-fill);
z-index: 1;
}
.fx-0765-root .gsp-box::before {
content: '';
position: absolute;
inset: calc(var(--gsp-width) * -1);
border-radius: calc(var(--gsp-radius) + var(--gsp-width));
background: conic-gradient(from var(--gsp-angle, 0deg), var(--gsp-colors));
z-index: -2;
animation: gspSpin var(--gsp-speed) linear infinite;
}
.fx-0765-root .gsp-box::after {
content: '';
position: absolute;
inset: var(--gsp-width);
background: var(--gsp-fill);
border-radius: max(0px, calc(var(--gsp-radius) - var(--gsp-width)));
z-index: -1;
}
.fx-0765-root .gsp-box:hover::before,
.fx-0765-root .gsp-box:focus-within::before {
animation-duration: var(--gsp-speed-hover);
filter: blur(var(--gsp-halo));
}
/* Stretched link: the whole box is clickable, and keyboard focus
or a tap on this link triggers the same state as hover. */
.fx-0765-root .gsp-link {
color: inherit;
text-decoration: none;
outline: none;
}
.fx-0765-root .gsp-link::after {
content: '';
position: absolute;
inset: 0;
border-radius: var(--gsp-radius);
}
.fx-0765-root .gsp-link:focus-visible::after {
outline: 2px solid var(--gsp-ring);
outline-offset: calc(var(--gsp-width) + 4px);
}
@keyframes gspSpin {
to {
--gsp-angle: 360deg;
}
}
@media (prefers-reduced-motion: reduce) {
.fx-0765-root .gsp-box::before,
.fx-0765-root .gsp-box:hover::before,
.fx-0765-root .gsp-box:focus-within::before {
animation: none;
}
}
CSS pur — aucun JavaScript requis.
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
--gsp-colors |
#ff0080, #ff8c00, #40e0d0, #7b2ff7, #ff0080 |
Liste des couleurs du dégradé, autant que vous voulez ; répétez la première à la fin pour éviter une cassure. |
--gsp-speed |
3s |
Durée d'un tour au repos. |
--gsp-speed-hover |
1s |
Durée d'un tour au survol, au focus et au toucher ; mettez la même valeur que --gsp-speed pour ne garder que le halo. |
--gsp-halo |
4px |
Flou de la bande au survol ; 0px supprime le halo. |
--gsp-width |
3px |
Débord de la bande de chaque côté du bord : la bande visible fait le double (6 px par défaut). |
--gsp-radius |
12px |
Arrondi de la boîte ; la bande et le masque suivent. La moitié de la hauteur donne une pilule. |
--gsp-w et --gsp-h |
200px et 120px |
Taille de la boîte ; auto laisse le contenu décider, et la largeur ne dépasse jamais le conteneur. |
--gsp-fill |
#0a0a0f |
Fond de la boîte et du masque intérieur. |
--gsp-ring |
#fff |
Couleur du contour de focus clavier. |
Le survol change la durée de l'animation (3 s → 1 s) sans la redémarrer : le navigateur garde le temps écoulé et recalcule où en est le tour, d'où un saut d'angle. Si vous préférez une transition sans saut, supprimez animation-duration de la règle de survol et gardez seulement le halo (filter).
Mettez votre contenu dans .gsp-box, réglez --gsp-h: auto pour que la hauteur suive le contenu et donnez-lui un peu de marge intérieure. Si la carte mène quelque part, gardez un lien .gsp-link à l'intérieur : il rend toute la carte cliquable et déclenche l'accélération au clavier.
Non : tout est rattaché à .fx-0765-root et l'angle n'est pas hérité, chaque boîte tourne pour elle-même. Une seule racine peut d'ailleurs contenir plusieurs .gsp-box, comme la grille de vignettes de l'exemple de streaming.