Skip to content

Watch Those Numbers Dance: How to Animate Value Changes on Your Website with CSS

As a graphic designer, I’m obsessed with creating websites that feel alive. That doesn’t mean glitter explosions (unless that’s your brand) — it means thoughtful movement. Subtle animations. Micro-interactions that spark joy.

One of my favorite little tricks? Making numbers change dynamically on your site — like a counter that ticks up when it comes into view. Think “Revenue: $1,000,000” climbing up instead of just appearing. It adds a sense of progress, excitement, and life to your data.

And good news — you don’t need heavy JavaScript to get started. Here’s how to animate number changes with CSS and just a sprinkle of JavaScript.

🔢 Why Animate Numbers?

Your brain loves movement — it notices it. When a number ticks up or changes, it’s like a visual cue that says:

“Hey! Something good is happening here.”

This works especially well for:

  • Stats on your homepage (like happy customers or total donations)
  • Progress bars or goals
  • Pricing discounts or countdowns

💻 The Code: CSS + a Touch of JS

Unfortunately, CSS alone can’t animate numbers like $0 → $1,000. But we can style them with CSS and animate the value with a teeny JavaScript function.

Here’s how:

1. HTML: Your Number Wrapper

<div class="stat">
  <span class="number" data-target="1000">0</span>+
</div>

2. CSS: Make It Pretty (and Optional Animation Styles)

.stat {
  font-size: 2rem;
  font-weight: bold;
  font-size: 50px;
  color: #5700FF;
}

.number {
  transition: all 0.3s ease-in-out;
}

3. JavaScript: Animate the Value Change

<script>
document.addEventListener("DOMContentLoaded", () => {
  const counters = document.querySelectorAll('.number');

  const animateCounter = (counter) => {
    const target = +counter.getAttribute('data-target');
    const duration = 6000; // total animation time in ms
    const frameRate = 60;
    const totalFrames = Math.round(duration / (1000 / frameRate));
    const increment = target / totalFrames;
    let current = 0;
    let frame = 0;

    const animate = () => {
      frame++;
      current += increment;
      if (frame < totalFrames) {
        counter.innerText = Math.ceil(current);
        requestAnimationFrame(animate);
      } else {
        counter.innerText = target;
      }
    };

    animate();
  };

  const observer = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        animateCounter(entry.target);
        observer.unobserve(entry.target); // Only animate once
      }
    });
  }, {
    threshold: 1 // Starts animation when 100% of the number is visible
  });

  counters.forEach(counter => {
    observer.observe(counter);
  });
});
</script>

✅ Bonus: This uses Intersection Observer to only animate the number when it scrolls into view — no wasted animations!

Example:

Animated Counter Example
0+
🎨 Designer Tips
  • Font choice matters — Use a monospaced or numeric-friendly font if you want that classic “ticker” feel.
  • Color contrast — Make your numbers pop (but check accessibility!). Use tools like Able for WCAG contrast checks.
  • Don’t overdo it — One or two animated stats per page is magical. A dozen? Feels like a game show.
✨ Final Thoughts

Animating numbers is a small touch that makes a big impression. It’s one of those designer details that says, “We care about experience.” Try it out on your own site or a client project, and watch how something as simple as $0 → $1000 can feel so satisfying.

If you give this a try or want help implementing it in your brand’s style, I’m all ears — and keyboards.

About Robert

Robert is a graphic designer specializing in branding, website design, and marketing. With a career spanning print magazines, agencies, nonprofits, and startups, Robert creates visually compelling and strategically driven designs. Passionate about building cohesive brand systems in Figma, he helps businesses craft memorable identities and high-performing websites. When not designing, you’ll find him enjoying coastal life, spending time with his German Shepherds, or tending to his ever-growing plant collection.