카운트업

Count-up

숫자가 0(또는 이전 값)에서 목표값까지 빠르게 올라가며 변하는 애니메이션. 대시보드의 통계·KPI 카드에서 흔합니다.

다른 이름: Number counter animationAnimated number
···
html
<div class="kpi"><span id="num">0</span><small>MAU</small></div>
css
.kpi{display:grid;justify-items:center;gap:4px}
#num{font:800 clamp(30px,11vmin,58px)/1 ui-monospace,monospace;color:var(--accent);font-variant-numeric:tabular-nums}
.kpi small{font:600 11px/1 sans-serif;letter-spacing:.14em;color:var(--muted)}
js
const el = document.getElementById('num');
const target = 48200;
function easeOut(t) { return 1 - Math.pow(1 - t, 3); }
function run() {
  const dur = 1600, start = performance.now();
  function frame(now) {
    const t = Math.min(1, (now - start) / dur);
    const v = Math.round(target * easeOut(t));
    el.textContent = v.toLocaleString('en-US');
    if (t < 1) requestAnimationFrame(frame); else setTimeout(run, 1200);
  }
  requestAnimationFrame(frame);
}
run();

CSS transition은 숫자 텍스트를 보간하지 못하므로, requestAnimationFrame으로 매 프레임 현재값을 계산해 textContent를 갱신하는 JS가 필요합니다. 진행률에 이징(보통 ease-out)을 적용하면 막판에 느려지며 도착하는 느낌을 줍니다.

CSS만으로도 @property로 숫자를 커스텀 프로퍼티로 등록해 흉내 낼 수 있지만, 아직 실무에서는 JS 구현이 더 흔합니다. 큰 수는 천 단위 콤마를 반드시 포맷팅하세요.

언제 쓰나

사용자가 화면에 들어왔을 때(또는 값이 바뀔 때) 한 번만 트리거하세요. 리스트의 숫자마다 반복하면 산만합니다.