Infinity Loop
Un point rose suivi de près par un halo flou parcourt sans fin un huit couché (∞) dessiné en trait fin, à vitesse constante, 5 s par boucle, sans jamais s'arrêter — CSS pur avec offset-path ; quand le visiteur demande moins d'animations, le point attend immobile en haut de la boucle droite.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. 3D comprend 50 effets, dont 8 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Sur un fond #0a0a0f haut d'au moins 300 px, .fx-0034-root place au milieu une scène de 300 × 200 px, .mp-infinity-scene. Le huit y est dessiné par un <svg> aux mêmes dimensions (viewBox="0 0 300 200"), en rose à 12 % sur 1,5 px d'épaisseur : quatre courbes de Bézier qui partent du croisement central (150, 100), bouclent à droite, repassent au croisement puis bouclent à gauche. Longueur totale : 479 px.
Le point de 16 px (#ec4899, lueur en box-shadow) et, sous lui, une pastille de 8 px rose à 40 % floutée par filter: blur(4px) sont ancrés au coin supérieur gauche de la scène. Leur offset-path: path(…) reprend mot pour mot le dessin du SVG, si bien que leur centre épouse le trait du huit : 0,1 px d'écart au plus, quel que soit le moteur testé. Une boucle de mpOrbit pousse offset-distance jusqu'à 100 % en 5 s, en linear, à l'infini : à peu près 96 px par seconde, aussi bien dans les virages qu'au croisement, et le tracé fermé ramène le point au centre, d'où il repart sans saccade.
Pour le halo, animation-delay: -4.8s : sur 5 s de boucle, démarrer 4,8 s en avance équivaut à traîner 0,2 s derrière, une vingtaine de pixels, dès la première image. Cette petite traînée rose indique le sens de la course. Le code n'a ni JavaScript ni id, et deux huit posés sur la même page tournent indépendamment. Si le système demande de réduire les animations, une media query qui ne vise que .fx-0034-root immobilise le point en haut de la boucle droite (18 % du parcours) et le halo juste avant lui (15 %).
Accessibilité
- Moins d'animations : quand le visiteur l'a demandé (
prefers-reduced-motion: reduce), point et halo restent posés sur la boucle droite, le halo du côté d'où arrive le point. Relevé dans Chromium, Firefox et WebKit : plus aucune animation active, pas un pixel qui bouge sur 800 ms. - Mouvement continu : la boucle ne s'arrête jamais d'elle-même. Évitez de la placer à côté d'un long texte à lire ; dans un exercice où suivre le point est le but (premier exemple), ajoutez un bouton qui pose
animation-play-state: pausedsur les deux ronds. - Contraste du tracé : le rose à 12 % est un guide discret. Si le dessin du huit compte (un plateau d'examen), montez-le à 30 % ou plus, ou en pointillés blancs sur fond sombre comme dans le deuxième exemple.
- Pas d'interaction : souris, doigt et clavier n'ont aucun effet sur le huit. Cachez la racine aux lecteurs d'écran (
aria-hidden="true") et écrivez la consigne à côté.
Compatibilité navigateur
CSS pur : offset-path: path(), offset-distance animé, filter: blur(), SVG en ligne pour le tracé. Aucune dépendance, aucun JavaScript. Mesuré dans Chromium 151, Firefox 153 et WebKit 26.5 : point et halo centrés sur la ligne (écart inférieur à 0,1 px), halo derrière le point, arrêt sous mouvement réduit, deux copies indépendantes.
Sans offset-path (Safari avant 16), le huit s'affiche mais le point et son halo restent immobiles dans le coin haut gauche de la scène (mesuré en retirant la propriété). Un @supports not (offset-path: path("M 0 0")) peut les masquer.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0034-root">
<div class="mp-infinity-scene"> <!-- 300 × 200 px -->
<svg viewBox="0 0 300 200" fill="none">
<path d="M150,100 C150,55 210,30 230,70 … C90,170 150,145 150,100" …></path>
</svg>
<div class="mp-infinity-glow"></div> <!-- halo flou, 0,2 s derrière -->
<div class="mp-infinity-dot"></div>
</div>
</div>
Paiement unique, sans abonnement — le code est à toi pour toujours
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Durée d'une boucle (CSS — 5s dans les deux animation) |
5 s | Changez-la sur le point ET le halo, et recalculez le délai du halo : délai = -(durée - retard). Pour 8 s et 0,2 s de retard : -7.8s. |
Distance du halo (CSS — animation-delay de .mp-infinity-glow) |
-4.8s (0,2 s de retard) |
-4.6s l'éloigne à 0,4 s, une quarantaine de pixels : la traînée se voit davantage. |
Agrandir (CSS — transform: scale() sur .mp-infinity-scene) |
aucun (huit de 168 × 100 px) | offset-path est en pixels : un scale() agrandit la ligne et la trajectoire ensemble, là où un changement de largeur ne déformerait que la ligne. |
Visibilité du tracé (CSS — .mp-infinity-scene path { stroke: … }) |
rose à 12 %, 1,5 px | La règle CSS l'emporte sur l'attribut stroke du SVG. Des pointillés (stroke-dasharray) donnent un air de piste ou de marquage au sol. |
Couleurs (CSS — background et box-shadow) |
rose #ec4899 |
Changez la couleur du point, de son box-shadow et du halo ensemble, sinon la traînée paraît d'une autre teinte. |
Sens de parcours (CSS — reverse dans animation) |
boucle de droite vers le haut d'abord | Ajoutez reverse sur les deux ronds : le halo reste derrière le point, son délai n'a pas à changer. |
FAQ
d du SVG et offset-path), avec les mêmes coordonnées, dans le repère de la scène de 300 × 200 px. Gardez un tracé fermé qui revient à son point de départ, sinon le point sautera d'un bout à l'autre à chaque tour. Pour simplement l'agrandir, transform: scale() sur la scène suffit.