{ CF }

15 CSS Number Counter Animations

Fitness Step Counter

Warm pastel scene with morphing blob shapes in the background. A circular gradient ring fills to 75% with a bouncing flame at the center. The step count springs up with a playful overshoot. Milestone pills mark 5K and 7.5K as done, 10K actively pulsing. Built for health apps and wearable dashboards.

CSS + JS MIT licensed

Fitness Step Counter the 9th of 15 designs in the 15 CSS Number Counter Animations collection. The design pairs CSS styling with a small amount of JavaScript for interactivity. Copy the HTML, CSS and JavaScript panels below into your project — the JS is self-contained, has zero dependencies, and is safe to drop into any framework (React, Vue, Svelte, plain HTML). The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.

Live preview

Open in playground

The code

<div class="cnc-fit">
  <div class="cnc-fit-shape cnc-fit-s1"></div>
  <div class="cnc-fit-shape cnc-fit-s2"></div>
  <div class="cnc-fit-shape cnc-fit-s3"></div>
  <div class="cnc-fit-block">
    <div class="cnc-fit-day-label">Tuesday · May 19</div>
    <div class="cnc-fit-ring-outer">
      <svg class="cnc-fit-ring-svg" width="220" height="220" viewBox="0 0 220 220">
        <defs><linearGradient id="cnc-fit-ringGrad" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#ffaa66"/><stop offset="100%" stop-color="#ff4e4e"/></linearGradient></defs>
        <circle class="cnc-fit-ring-track" cx="110" cy="110" r="95"/>
        <circle class="cnc-fit-ring-prog"  cx="110" cy="110" r="95"/>
      </svg>
      <div class="cnc-fit-ring-center">
        <div class="cnc-fit-ring-emoji">🔥</div>
        <div class="cnc-fit-ring-num"><span class="cnc-fit-pct" data-target="75">0</span>%</div>
        <div class="cnc-fit-ring-unit">of goal</div>
      </div>
    </div>
    <div class="cnc-fit-step-num" data-steps data-target="7534">0</div>
    <div class="cnc-fit-step-label">Steps Today</div>
    <div class="cnc-fit-milestones">
      <div class="cnc-fit-ms cnc-fit-ms-done">5K</div>
      <div class="cnc-fit-ms cnc-fit-ms-done">7.5K</div>
      <div class="cnc-fit-ms cnc-fit-ms-active">10K</div>
      <div class="cnc-fit-ms cnc-fit-ms-next">15K</div>
    </div>
  </div>
</div>
.cnc-fit { min-height: 540px; display: grid; place-items: center; padding: 48px 24px; background: #fff4e6; position: relative; overflow: hidden; font-family: 'Nunito', sans-serif; }
.cnc-fit *, .cnc-fit *::before, .cnc-fit *::after { box-sizing: border-box; }
.cnc-fit-shape { position: absolute; pointer-events: none; }
.cnc-fit-s1 { width: 320px; height: 320px; background: #ffe0c2; top: -80px; right: -80px; border-radius: 40% 60% 55% 45%; animation: cnc-fit-morph 10s ease-in-out infinite; }
.cnc-fit-s2 { width: 240px; height: 240px; background: #ffd0f0; bottom: -60px; left: -60px; border-radius: 60% 40% 45% 55%; animation: cnc-fit-morph 14s ease-in-out infinite reverse; }
.cnc-fit-s3 { width: 140px; height: 140px; background: #c8f0e0; top: 30%; right: 5%; border-radius: 55% 45%; animation: cnc-fit-morph 8s ease-in-out infinite; opacity: 0.7; }
@keyframes cnc-fit-morph { 0%, 100% { border-radius: 60% 40% 55% 45%; } 50% { border-radius: 40% 60% 45% 55%; } }
.cnc-fit-block { position: relative; z-index: 1; text-align: center; padding: 32px; width: 420px; max-width: 100%; }
.cnc-fit-day-label { font-size: 11px; letter-spacing: 3px; text-transform: uppercase; color: #ffaa66; font-weight: 700; margin-bottom: 28px; opacity: 0; animation: cnc-fit-pop 0.5s cubic-bezier(0.34,1.56,0.64,1) 0.0s forwards; }
.cnc-fit-ring-outer { width: 220px; height: 220px; margin: 0 auto 24px; position: relative; opacity: 0; animation: cnc-fit-pop 0.7s cubic-bezier(0.34,1.56,0.64,1) 0.15s forwards; }
.cnc-fit-ring-svg { transform: rotate(-90deg); overflow: visible; }
.cnc-fit-ring-track { fill: none; stroke: #ffe8d0; stroke-width: 14; stroke-linecap: round; }
.cnc-fit-ring-prog { fill: none; stroke: url(#cnc-fit-ringGrad); stroke-width: 14; stroke-linecap: round; stroke-dasharray: 597; stroke-dashoffset: 597; filter: drop-shadow(0 0 8px rgba(255,130,60,0.4)); animation: cnc-fit-ringFill 2s cubic-bezier(0.22,1,0.36,1) 0.5s forwards; }
@keyframes cnc-fit-ringFill { to { stroke-dashoffset: 149; } }
.cnc-fit-ring-center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.cnc-fit-ring-emoji { font-size: 38px; animation: cnc-fit-bounce 2s ease-in-out infinite; line-height: 1; margin-bottom: 4px; }
@keyframes cnc-fit-bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
.cnc-fit-ring-num { font-family: 'Righteous', sans-serif; font-size: 32px; color: #222; letter-spacing: -1px; line-height: 1; }
.cnc-fit-ring-unit { font-size: 10px; letter-spacing: 2px; text-transform: uppercase; color: #ccc; font-weight: 700; margin-top: 3px; }
.cnc-fit-step-num { font-family: 'Righteous', sans-serif; font-size: clamp(64px, 14vw, 88px); color: #1a1a1a; letter-spacing: -2px; line-height: 1; opacity: 0; animation: cnc-fit-pop 0.8s cubic-bezier(0.34,1.56,0.64,1) 0.3s forwards; display: inline-block; }
.cnc-fit-step-label { font-size: 11px; letter-spacing: 3px; text-transform: uppercase; color: #ccc; font-weight: 700; margin-top: 4px; margin-bottom: 28px; opacity: 0; animation: cnc-fit-pop 0.5s ease 0.45s forwards; }
.cnc-fit-milestones { display: flex; gap: 8px; justify-content: center; opacity: 0; animation: cnc-fit-pop 0.5s ease 0.55s forwards; }
.cnc-fit-ms { padding: 8px 16px; border-radius: 100px; font-size: 12px; font-weight: 700; display: flex; align-items: center; gap: 6px; border: 2px solid transparent; }
.cnc-fit-ms-done { background: #fff; border-color: #22c55e; color: #22c55e; }
.cnc-fit-ms-done::before { content: '✓'; }
.cnc-fit-ms-next { background: #fff; border-color: #e0e0e0; color: #ccc; }
.cnc-fit-ms-active { background: #ff823c; color: #fff; animation: cnc-fit-pulse 1.5s ease-in-out infinite; }
@keyframes cnc-fit-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(255,130,60,0.4); } 50% { box-shadow: 0 0 0 8px rgba(255,130,60,0); } }
@keyframes cnc-fit-pop { from { opacity: 0; transform: scale(0.85); } to { opacity: 1; transform: scale(1); } }
@media (prefers-reduced-motion: reduce) {
  .cnc-fit-shape, .cnc-fit-day-label, .cnc-fit-ring-outer, .cnc-fit-ring-prog, .cnc-fit-ring-emoji, .cnc-fit-step-num, .cnc-fit-step-label, .cnc-fit-milestones, .cnc-fit-ms-active { animation: none; opacity: 1; transform: none; }
  .cnc-fit-ring-prog { stroke-dashoffset: 149; }
}
(function () {
  var root = document.querySelector('.cnc-fit');
  if (!root) return;
  function ease(t) { return 1 - Math.pow(1 - t, 4); }
  setTimeout(function () {
    var start = performance.now(), dur = 2200;
    var stepsEl = root.querySelector('[data-steps]');
    var pctEl   = root.querySelector('.cnc-fit-pct');
    var GOAL    = 10000;
    var stepsTarget = parseFloat(stepsEl.dataset.target);
    function tick(now) {
      var t = Math.min((now - start) / dur, 1), e = ease(t), v = e * stepsTarget;
      stepsEl.textContent = Math.round(v).toLocaleString();
      pctEl.textContent = Math.round(v / GOAL * 100);
      if (t < 1) requestAnimationFrame(tick);
    }
    requestAnimationFrame(tick);
  }, 300);
})();

Search CodeFronts

Loading…