Progress Ring
Anneau SVG en dégradé qui se remplit jusqu'à sa valeur quand il apparaît, puis glisse vers chaque nouvelle valeur : un vrai indicateur de progression.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Data comprend 28 effets, dont 1 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
La valeur se règle à un seul endroit : aria-valuenow sur .prng-ring (de 0 à 100 par défaut, ou entre aria-valuemin et aria-valuemax). Le script en tire la part à peindre, écrit le texte du centre (« 75 % » en français, « 75% » en anglais, selon l'attribut lang de la page) et le recopie dans aria-valuetext. Le chiffre affiché et l'anneau ne peuvent donc plus se contredire.
L'anneau est un cercle SVG de rayon 50 dont le trait fait 314,16 unités (sa circonférence). Tant qu'il n'est pas visible, il reste vide ; dès qu'il l'est à moitié (IntersectionObserver), le script pose --prng-offset et la transition CSS de 2 s (ease-out) le remplit en partant du haut. Cela n'arrive qu'une fois.
Ensuite, chaque nouvelle valeur écrite dans aria-valuenow (par votre code, après une action de l'utilisateur) est suivie : un MutationObserver met à jour le texte et l'anneau glisse de l'ancienne valeur vers la nouvelle. Chaque anneau reçoit son propre id de dégradé, si bien que plusieurs anneaux dans une page, même un caché, gardent leurs couleurs ; rien n'est ajouté sur window.
Accessibilité
- Rôle :
role="progressbar"avecaria-valuemin,aria-valuemax,aria-valuenowetaria-valuetexttenus à jour. Donnez un nom juste avecaria-label(« Profil complété », « Leçon 3 ») : sans lui, l'annonce se limite à « Progression, 75 % ». - Dessin masqué : le SVG porte
aria-hidden="true"; le lecteur d'écran n'annonce que la valeur, pas les cercles. - Mouvement réduit : sous
prefers-reduced-motion: reduce, la transition est coupée et l'anneau affiche sa valeur dès qu'il apparaît ; les nouvelles valeurs s'appliquent aussi sans glissement. - Changement annoncé ? Un rôle progressbar n'est pas une zone live : une nouvelle valeur est lue quand l'utilisateur revient sur l'anneau. Pour l'annoncer tout de suite, ajoutez votre propre message dans une zone
aria-live.
Compatibilité navigateur
SVG, variables CSS et JavaScript sans dépendance (environ 2 Ko). Mesuré le 08/11/2026 dans Chromium 151, Firefox 153 et WebKit 26.5 (Playwright) : remplissage à l'apparition, anneau placé plus bas qui attend le défilement, nouvelle valeur sur la 2e copie sans toucher la 1re, 390 px, mouvement réduit, aucune erreur. Versions tirées de @mdn/browser-compat-data : IntersectionObserver fixe le minimum.
Sans IntersectionObserver, l'anneau prend sa valeur au chargement. Sans JavaScript, l'anneau reste vide mais le texte du HTML (« 75 % ») reste lisible.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0224-root">
<div class="prng-ring" role="progressbar" aria-label="Progression" aria-valuemin="0" aria-valuemax="100" aria-valuenow="75">
<svg class="prng-svg" viewBox="0 0 120 120" aria-hidden="true">
<defs><linearGradient id="prng-grad">…</linearGradient></defs>
<circle class="prng-track"></circle>
<circle class="prng-fill"></circle>
</svg>
<span class="prng-text">75 %</span>
</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 |
|---|---|---|
Valeur (HTML — aria-valuenow sur .prng-ring) |
75 | Modifiez l'attribut, au départ ou plus tard en JavaScript (anneau.setAttribute('aria-valuenow', 90)) : texte et anneau suivent. |
Bornes (HTML — aria-valuemin et aria-valuemax) |
0 et 100 | Pour 3 leçons sur 8 : aria-valuemin="0" aria-valuemax="8" aria-valuenow="3" ; le centre affiche alors 38 %. |
Nom pour les lecteurs d'écran (HTML — aria-label) |
Progression | Décrivez ce qui progresse : « Profil complété », « Objectif de collecte ». |
Couleurs (CSS — --prng-from, --prng-to, --prng-track) |
#6366f1 → #d946ef · indigo à 20 % | Les deux teintes du dégradé et la couleur de la partie vide. |
Taille et épaisseur (CSS — --prng-size, --prng-stroke) |
120px · 8 | Le texte central fait 20 % de la taille. L'épaisseur est en unités du dessin (120 de large) : montez-la sous 50 px pour que l'anneau reste visible. |
Durée (CSS — --prng-duration) |
2s | Durée du remplissage et des glissements suivants. |
Fond, texte et hauteur (CSS — --prng-bg, --prng-text, --prng-height) |
#0a0a0f · #fff · 300px | Sur une page claire : --prng-bg:transparent; --prng-text:#0f172a; --prng-height:0px. |
FAQ
aria-valuenow à chaque étape (fichier envoyé, leçon terminée, champ rempli). Le script surveille cet attribut : pas de fonction à appeler, pas de variable globale..prng-text par CSS et placez votre élément par-dessus l'anneau (position absolue sur un parent commun), comme l'avatar de l'exemple. La valeur reste annoncée grâce à aria-valuetext.