Back to CSS Number Counter Animations CO₂ Sustainability Impact CSS + JS
Share
HTML
<div class="cnc-co2">
  <div class="cnc-co2-bg"><div class="cnc-co2-blob cnc-co2-blob1"></div><div class="cnc-co2-blob cnc-co2-blob2"></div><div class="cnc-co2-blob cnc-co2-blob3"></div></div>
  <div class="cnc-co2-block">
    <div class="cnc-co2-label-top">Environmental Impact</div>
    <div class="cnc-co2-icon-ring">
      <svg width="88" height="88" viewBox="0 0 88 88" fill="none">
        <circle cx="44" cy="44" r="40" stroke="rgba(79,192,102,0.25)" stroke-width="1" stroke-dasharray="6 8" stroke-linecap="round"/>
      </svg>
      🌿
    </div>
    <div class="cnc-co2-count-wrap">
      <div class="cnc-co2-count-main"><span class="cnc-num" data-target="12480" data-format="round">0</span></div>
      <span class="cnc-co2-count-unit">tonnes CO₂ saved</span>
    </div>
    <div class="cnc-co2-count-desc">by our fleet this year, equivalent to planting a small forest.</div>
    <div class="cnc-co2-strip">
      <div class="cnc-co2-strip-head"><span>Annual Target</span><span><span class="cnc-num" data-target="68" data-format="round">0</span>% Complete</span></div>
      <div class="cnc-co2-strip-track"><div class="cnc-co2-strip-fill"></div></div>
    </div>
    <div class="cnc-co2-equiv">
      <div class="cnc-co2-eq-item"><div class="cnc-co2-eq-icon">🌳</div><div class="cnc-co2-eq-val"><span class="cnc-num" data-target="499" data-format="round">0</span></div><div class="cnc-co2-eq-label">Trees equiv.</div></div>
      <div class="cnc-co2-eq-item"><div class="cnc-co2-eq-icon">✈️</div><div class="cnc-co2-eq-val"><span class="cnc-num" data-target="4992" data-format="round">0</span></div><div class="cnc-co2-eq-label">Flights offset</div></div>
      <div class="cnc-co2-eq-item"><div class="cnc-co2-eq-icon">🏠</div><div class="cnc-co2-eq-val"><span class="cnc-num" data-target="1686" data-format="round">0</span></div><div class="cnc-co2-eq-label">Homes/yr</div></div>
    </div>
  </div>
</div>
CSS
.cnc-co2 { min-height: 620px; display: grid; place-items: center; padding: 48px 24px; background: #061208; position: relative; overflow: hidden; font-family: 'Mulish', sans-serif; }
.cnc-co2 *, .cnc-co2 *::before, .cnc-co2 *::after { box-sizing: border-box; }
.cnc-co2-bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.cnc-co2-blob { position: absolute; border-radius: 50%; filter: blur(80px); opacity: 0.18; animation: cnc-co2-drift 14s ease-in-out infinite; }
.cnc-co2-blob1 { width: 500px; height: 500px; background: #1a7a2e; top: -100px; left: -100px; animation-delay: 0s; }
.cnc-co2-blob2 { width: 400px; height: 400px; background: #0d5c22; bottom: -80px; right: -80px; animation-delay: -5s; }
.cnc-co2-blob3 { width: 300px; height: 300px; background: #4fc066; top: 50%; left: 50%; transform: translate(-50%, -50%); animation-delay: -10s; opacity: 0.06; }
@keyframes cnc-co2-drift { 0%, 100% { transform: scale(1) translate(0, 0); } 33% { transform: scale(1.1) translate(30px, -20px); } 66% { transform: scale(0.95) translate(-20px, 30px); } }
.cnc-co2-block { position: relative; z-index: 1; text-align: center; padding: 32px; width: 440px; max-width: 100%; }
.cnc-co2-label-top { font-family: 'Unbounded', sans-serif; font-size: 8px; letter-spacing: 5px; text-transform: uppercase; color: rgba(79,192,102,0.5); font-weight: 300; margin-bottom: 40px; opacity: 0; animation: cnc-co2-rise 0.5s ease 0.1s forwards; }
.cnc-co2-icon-ring { width: 72px; height: 72px; border-radius: 50%; border: 1px solid rgba(79,192,102,0.2); display: flex; align-items: center; justify-content: center; margin: 0 auto 32px; font-size: 28px; position: relative; opacity: 0; animation: cnc-co2-rise 0.6s ease 0.2s forwards; box-shadow: 0 0 30px rgba(79,192,102,0.12), inset 0 0 20px rgba(79,192,102,0.05); }
.cnc-co2-icon-ring::before { content: ''; position: absolute; inset: -4px; border-radius: 50%; border: 1px solid rgba(79,192,102,0.08); }
.cnc-co2-icon-ring svg { position: absolute; inset: -8px; animation: cnc-co2-slowSpin 10s linear infinite; }
@keyframes cnc-co2-slowSpin { to { transform: rotate(360deg); } }
.cnc-co2-count-wrap { opacity: 0; animation: cnc-co2-rise 0.8s cubic-bezier(0.22,1,0.36,1) 0.35s forwards; margin-bottom: 6px; }
.cnc-co2-count-main { font-family: 'Unbounded', sans-serif; font-size: clamp(64px, 14vw, 96px); font-weight: 900; color: #fff; line-height: 1; letter-spacing: -3px; text-shadow: 0 0 60px rgba(79,192,102,0.4); }
.cnc-co2-count-unit { font-family: 'Unbounded', sans-serif; font-size: 18px; font-weight: 300; color: #4fc066; letter-spacing: 2px; margin-top: 6px; text-transform: uppercase; display: block; opacity: 0; animation: cnc-co2-rise 0.5s ease 0.5s forwards; }
.cnc-co2-count-desc { font-size: 13px; color: rgba(255,255,255,0.3); font-weight: 300; margin-top: 24px; line-height: 1.6; max-width: 280px; margin-left: auto; margin-right: auto; opacity: 0; animation: cnc-co2-rise 0.5s ease 0.6s forwards; }
.cnc-co2-strip { margin-top: 40px; opacity: 0; animation: cnc-co2-rise 0.5s ease 0.7s forwards; }
.cnc-co2-strip-head { display: flex; justify-content: space-between; font-size: 9px; letter-spacing: 2px; text-transform: uppercase; color: rgba(255,255,255,0.2); margin-bottom: 10px; }
.cnc-co2-strip-track { height: 3px; background: rgba(255,255,255,0.05); border-radius: 2px; overflow: hidden; }
.cnc-co2-strip-fill { height: 100%; width: 68%; background: linear-gradient(90deg, #1a6b2e, #4fc066); border-radius: 2px; box-shadow: 0 0 10px rgba(79,192,102,0.5); transform: scaleX(0); transform-origin: left; animation: cnc-co2-fillIn 2s ease 0.9s forwards; }
@keyframes cnc-co2-fillIn { to { transform: scaleX(1); } }
.cnc-co2-equiv { margin-top: 28px; display: flex; gap: 20px; justify-content: center; opacity: 0; animation: cnc-co2-rise 0.5s ease 0.85s forwards; }
.cnc-co2-eq-item { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.cnc-co2-eq-icon { font-size: 22px; }
.cnc-co2-eq-val { font-family: 'Unbounded', sans-serif; font-size: 16px; font-weight: 700; color: #4fc066; }
.cnc-co2-eq-label { font-size: 8px; letter-spacing: 2px; text-transform: uppercase; color: rgba(255,255,255,0.2); }
@keyframes cnc-co2-rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) {
  .cnc-co2-blob, .cnc-co2-label-top, .cnc-co2-icon-ring, .cnc-co2-count-wrap, .cnc-co2-count-unit, .cnc-co2-count-desc, .cnc-co2-strip, .cnc-co2-strip-fill, .cnc-co2-equiv, .cnc-co2-icon-ring svg { animation: none; opacity: 1; transform: none; }
  .cnc-co2-strip-fill { transform: scaleX(1); }
}
JS
(function () {
  var root = document.querySelector('.cnc-co2');
  if (!root) return;
  function ease(t) { return 1 - Math.pow(1 - t, 3); }
  setTimeout(function () {
    var start = performance.now(), dur = 2400;
    var nums = root.querySelectorAll('.cnc-num[data-target]');
    function tick(now) {
      var t = Math.min((now - start) / dur, 1), e = ease(t);
      nums.forEach(function (el) {
        var target = parseFloat(el.dataset.target);
        el.textContent = Math.round(e * target).toLocaleString();
      });
      if (t < 1) requestAnimationFrame(tick);
    }
    requestAnimationFrame(tick);
  }, 400);
})();