Le HTML contient déjà la valeur finale : <span class="ctup-value" data-target="8547">8 547</span>. Le script cherche chaque .ctup-value[data-target] placé dans une racine .fx-0223-root, remet l'affichage à 0, puis attend que le chiffre soit visible à moitié (IntersectionObserver, seuil 0,5). À ce moment il compte jusqu'à data-target en 2 secondes avec un ralenti en fin de course (ease-out cubique), et ne recommence plus.
Le nombre de décimales vient de data-target lui-même : 6.4 affiche une décimale, 4.85 en affiche deux, 8547 aucune. Le format suit l'attribut lang le plus proche (celui de <html> en général) grâce à Intl.NumberFormat : « 8 547 » et « 6,4 » sur une page en français, « 8,547 » et « 6.4 » en anglais. Les chiffres ont la même largeur (tabular-nums), le bloc ne tremble donc pas pendant le comptage.
Chaque chiffre est réglé à part : plusieurs compteurs dans une racine, plusieurs racines dans la page, chacun part quand il devient visible. Le script ne déclare rien sur window. Un chiffre affiché plus tard (onglet, panneau replié, hidden retiré) compte au moment où il apparaît.
JavaScript sans dépendance (environ 2 Ko) et variables CSS. Mesuré le 08/11/2026 dans Chromium 151, Firefox 153 et WebKit 26.5 (Playwright) : comptage à l'apparition, compteur placé plus bas qui attend le défilement, deux copies, 390 px, mouvement réduit, format français et anglais, aucune erreur. Versions tirées de @mdn/browser-compat-data : IntersectionObserver fixe le minimum.
Chrome 51+✓ Complet (mesuré)
Firefox 55+✓ Complet (mesuré)
Safari 12.1+✓ Complet (mesuré dans WebKit)
Edge 79+✓ Complet (moteur Chromium)
iOS Safari 12.2+✓ Non vérifié sur appareil réel
Android Chrome 51+✓ Complet (moteur Chromium)