Glassmorphism✨ Premium

Superellipse Progress Ring

Trois anneaux de progression de 110 px tracés en superellipse : au survol, le tracé passe en 0,8 s d'un rond un peu carré (exposant 2,5) à un carré aux coins doux (exposant 5), comme une icône d'appli, avec une lueur de la couleur de l'anneau — et l'arc garde exactement son pourcentage pendant le changement de forme.

SVGAnimationProgress

Mis à jour le

Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Glassmorphism comprend 47 effets, dont 6 gratuits. Découvrir la catégorie →

3 exemples d'usage

Objectifs de rééducation du genou — appli de kinésithérapie — Superellipse Progress Ring exemple 1

① Objectifs de rééducation du genou — appli de kinésithérapie

QuandLe patient voit trois anneaux en semaine 4 : flexion du genou (115° sur 130°, 88 %), exercices à la maison (9 sur 12, 75 %) et marche du jour (4 200 pas sur 6 000, 70 %).
PourquoiLes anneaux donnent l'avancement d'un coup d'œil, sans chiffres à comparer. La forme superelliptique, proche des icônes du téléphone, rend l'écran familier ; au survol, l'anneau se « carre » et s'allume, ce qui montre celui qu'on regarde.
RéglagesCouleurs d'origine (violet #8b5cf6, cyan #06b6d4, vert #10b981), --dash-offset à 38,4, 80 et 96 (320 × (1 − part)). Libellés traduits ; colonnes de 156 px avec le détail sous chaque anneau.
Places libres dans les parkings relais — appli d'une métropole — Superellipse Progress Ring exemple 2

② Places libres dans les parkings relais — appli d'une métropole

QuandAvant de partir, l'automobiliste compare trois parkings relais : 82 %, 97 % et 45 % d'occupation, avec le nombre de places libres sous chacun.
PourquoiUn anneau par parking, rempli selon l'occupation : la comparaison est visuelle, et la couleur dit la décision (vert, il reste de la place ; rouge, inutile d'y aller). Le nombre de places libres, en gros sous l'anneau, double l'information pour qui ne distingue pas les couleurs.
RéglagesCouleurs passées en code de remplissage : orange #f59e0b, rouge #ef4444, vert #22c55e (trait et --ring-color, pour que la lueur suive) ; --dash-offset 57,6, 9,6 et 176. Fond de plan de ville en dégradés sombres.
Progression d'un livre audio — appli de bibliothèque sonore — Superellipse Progress Ring exemple 3

③ Progression d'un livre audio — appli de bibliothèque sonore

QuandL'auditeur voit où il en est de ses trois livres en cours : 62 %, 18 % et 91 %, avec le chapitre et le temps restant.
PourquoiL'anneau superelliptique s'accorde aux vignettes carrées des couvertures : au survol, il prend presque la forme de la couverture qu'il entoure. Le remplissage autour de la couverture se lit comme un « reste à écouter ».
RéglagesL'étiquette centrale accueille la couverture (58 px, rayon 14 px) à la place du pourcentage, reporté en dessous ; couleurs prises sur les couvertures (#f97316, #14b8a6, #e879f9) ; --dash-offset 121,6, 262,4 et 28,8.

Comment ça marche

Chaque .se-progress (110 × 110 px) contient un SVG viewBox="0 0 110 110" tourné de −90° pour que l'arc parte de midi, et deux tracés : la piste .se-bg (trait de 6 px, blanc à 8 %) et l'arc .se-fill (6 px, bouts arrondis, couleur en style). L'arc est un pointillé : stroke-dasharray: var(--dash-total) (320) et stroke-dashoffset: var(--dash-offset). Avec pathLength="320" sur l'arc, la longueur du tracé vaut 320 quelle que soit sa forme : la part remplie est donc (320 − décalage) ÷ 320 — 64 donne 80 %, 176 donne 45 %. Au centre, .se-label affiche la valeur en 20,8 px graisse 800 et un libellé en capitales de 8,8 px à 60 % d'opacité.

La forme vient du JavaScript : superellipsePath(cx, cy, rx, ry, n, segments) calcule 72 segments de la courbe |x|^n + |y|^n = 1. Exposant 2 : un cercle ; 2,5 : un rond légèrement carré (la forme de repos) ; 5 : un carré aux coins très arrondis, proche d'une icône d'appli (la forme au survol). Au chargement, le script pose la forme 2,5 sur chaque anneau ; mouseenter passe à 5, mouseleave revient à 2,5. Le CSS transition: d .8s ease fait le morph : mesuré dans Chromium 151 et Firefox 153, la longueur réelle du tracé passe de 320,7 à 352,5 en 0,8 s (325, 333, 341, 346, 350, 351, 352 par pas de 100 ms), sans saut. Au survol, l'arc reçoit aussi drop-shadow(0 0 6px var(--ring-color)). Changer --dash-offset en JavaScript anime le remplissage en 1 s avec un dépassement d'environ 10 % de la course (cubic-bezier(.34, 1.56, .64, 1) : mesuré, de 64 à 0 le décalage descend à −6 avant de revenir à 0).

Trois réglages tiennent le morph et la valeur justes. La forme de repos est posée par le script dès le chargement, en 72 segments comme la forme de survol : un anneau dessiné en courbes de Bézier ne s'interpolerait pas vers 72 segments droits, et le premier survol sauterait d'un coup (307,8 → 352,5, mesuré), avec un arc qui partirait de 9 h au lieu de midi. pathLength="320" fixe l'échelle du pointillé : les tracés mesurent 307,8 à 352,5 selon la forme, et sans cet attribut l'anneau « 80 % » en montrerait 83 % au repos et 73 % au survol. Aucune animation décorative sur le <svg> : faire varier son border-radius ne changerait rien, il n'a ni fond ni bordure.

Accessibilité

  • Lecteurs d'écran : le SVG n'a pas de texte et l'étiquette est un simple div (« 80% Storage ») : la valeur est lue, mais rien ne dit qu'il s'agit d'une progression. Ajoutez sur .se-progress role="progressbar", aria-valuenow="80", aria-valuemin="0", aria-valuemax="100" et un aria-label, et aria-hidden="true" sur le SVG. Les scènes de cette page mettent un role="img" et une phrase complète sur chaque colonne.
  • Clavier : les anneaux ne sont pas focalisables (mesuré : Tab ne s'y arrête pas) et le morph n'est déclenché que par la souris. Comme il ne porte aucune information — la valeur est la même dans les deux formes —, rien n'est perdu au clavier. Si les anneaux deviennent cliquables, faites-en des liens ou des boutons et appelez le même changement de forme sur focus / blur.
  • Contraste : la valeur blanche mesure 19,8:1 sur #0a0a0f et le libellé à 60 % 7,3:1. Les arcs violet (4,7:1), cyan (8,1:1) et vert (7,8:1) dépassent les 3:1 demandés pour un graphique ; la piste à 8 % (1,2:1) n'est qu'un repère. L'effet est conçu pour un fond sombre : sur fond clair, l'étiquette blanche disparaît — donnez alors --text-primary foncé sur .demo-preview.
  • Mouvement : morph de 0,8 s au survol et remplissage de 1 s quand la valeur change, sans boucle. Pour respecter la préférence : @media (prefers-reduced-motion: reduce) { .se-progress .se-fill { transition: none } } — la forme et la valeur changent alors d'un coup.

Compatibilité navigateur

SVG, propriété CSS d et sa transition, pathLength, stroke-dasharray/stroke-dashoffset, variables CSS, filter: drop-shadow(). JavaScript : Math.sign, Math.pow, querySelectorAll().forEach, aucune bibliothèque. Mesuré collé dans une page vierge : Chromium 151 et Firefox 153 interpolent le tracé (morph progressif en 0,8 s) ; WebKit 26.5 (Safari) ne connaît pas la propriété CSS d (getComputedStyle(path).d vide) : le tracé change bien de forme au survol, mais d'un coup, sans transition. Dans les trois moteurs, la part remplie reste juste (pathLength) et le remplissage animé fonctionne (même courbe à dépassement, mesurée).

Chrome 52+✓ Complet
Firefox 97+✓ Complet
Safari (toutes versions)✓ Partiel : la forme change au survol, sans morph progressif
Edge 79+✓ Complet
Mobile iOS✓ Partiel : pas de survol, donc pas de morph au doigt ; anneaux et valeurs justes
Android Chrome✓ Complet à la souris ; au doigt, le changement de forme dépend des événements souris simulés (non mesuré)

Sans transition de d (Safari, Firefox avant 97), la forme passe directement de 2,5 à 5 : l'anneau reste juste, seul le glissement disparaît. Sans JavaScript, les anneaux restent dessinés par les courbes de Bézier du HTML (forme ronde), arc à la bonne valeur grâce à pathLength, mais sans morph. Pour un morph progressif partout, il faudrait animer l'exposant en JavaScript (requestAnimationFrame, recalcul du tracé à chaque image) au lieu de la transition CSS.

Le code

Structure HTML à coller dans votre page (le CSS + JS sont inclus avec Premium) :

index.html — structure
<div class="demo-preview">
  <div class="se-progress-wrap">
    <div class="se-progress" style="--ring-color: #8b5cf6; --dash-total: 320; --dash-offset: 64;">
      <svg viewBox="0 0 110 110">
        <path class="se-bg" d="…"></path>
        <path class="se-fill" pathLength="320" style="stroke: #8b5cf6;" d="…"></path>
      </svg>
      <div class="se-label">80%<small>…</small></div>
    </div>
    …
  </div>
</div>
Débloquer le code complet — 9,90 € TTC/mois

Le code complet HTML + CSS + JS de Superellipse Progress Ring, prêt à coller — et les 840 effets. Ou 299 € TTC une fois, accès à vie.

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
Valeur (HTML — --dash-offset dans le style de .se-progress) 64 · 176 · 96 (80 %, 45 %, 70 %) --dash-offset = 320 × (1 − part). Modifié en JavaScript (el.style.setProperty('--dash-offset', v)), il anime le remplissage en 1 s avec un léger dépassement. Pensez à changer aussi le texte de .se-label.
Formes de repos et de survol (JS — les deux morph(2.5) et morph(5)) exposant 2,5 au repos, 5 au survol 2 donne un cercle parfait au repos (contraste maximal avec le survol) ; 4 ou 5 au repos donne des anneaux déjà carrés, comme des icônes. Au-delà de 8, les coins deviennent presque vifs.
Durée du morph (CSS — transition: … d .8s) 0,8 s, ease 0,4 s pour une réponse vive. Sans effet dans Safari, qui n'anime pas la propriété d.
Couleur (HTML — style="stroke: …" sur l'arc et --ring-color sur .se-progress) #8b5cf6 · #06b6d4 · #10b981 Changez les deux ensemble : --ring-color colore la lueur du survol. Visez 3:1 contre le fond.
Épaisseur et taille (CSS — stroke-width: 6, .se-progress { width/height: 110px }) 6 sur 110 px Le SVG s'adapte à la taille de la boîte ; le trait grossit en proportion. Les tracés sont calculés avec un rayon de 49 dans une boîte de 110 : il reste 6 unités de marge, donc un trait de plus de 12 est rogné par le bord du SVG — réduisez alors le rayon (les deux 49 de l'appel superellipsePath).
Précision du tracé (JS — 6e argument de superellipsePath) 72 segments Les formes de repos et de survol doivent garder le même nombre de segments, sinon la transition redevient sèche. 48 suffit pour 80 px ; 120 pour un anneau de 300 px.

FAQ

Parce que le morph repose sur la transition de la propriété CSS d (le tracé d'un <path>), que Safari ne gère pas : mesuré dans WebKit 26.5, getComputedStyle(path).d est vide et la longueur du tracé passe de 320,7 à 352,5 d'un coup. La forme et la valeur restent justes ; seul le glissement manque. Chrome, Edge et Firefox (depuis la 97) interpolent le tracé. Pour un rendu identique partout, animez l'exposant en JavaScript image par image.
Oui : pathLength="320" déclare au navigateur que le tracé mesure 320, quelle que soit sa longueur réelle (307,8 à 352,5 selon la forme). Le pointillé de 320 représente donc toujours 100 %, et un décalage de 64 toujours 80 %. Sans cet attribut, l'anneau à 80 % en montrerait 83 % au repos et 73 % au survol.
Démarrez avec --dash-offset: 320 (anneau vide) dans le HTML, puis posez la vraie valeur après le premier affichage, avec deux requestAnimationFrame imbriqués : requestAnimationFrame(() => requestAnimationFrame(() => el.style.setProperty('--dash-offset', 64))). Avec un seul, Firefox applique directement la valeur finale, sans transition (mesuré). La transition du code vendu (1 s, cubic-bezier(.34, 1.56, .64, 1)) remplit alors l'arc en dépassant d'environ 10 % de la course avant de revenir — mesuré dans les trois moteurs : 320 → 39 → 64.