跳到正文

数字滚动

Count Up

数字从 0 快速滚到目标值,然后停住。

  • 又叫:
  • 数字递增
  • 数值动画
  • 计数动画
  • count up
  • number counter
  • animated counter
展厅
排版与文字
形态
固定舞台
播放
重播
关键词
需要 JS / 浏览器 API / 字体特性 / 主线程每帧 / 可以直接用
T-06形态 固定舞台播放 重播Count Up

参数工作台

复制给 AI

随参数实时更新

做一个数字滚动(count up):数字在 1200ms 内用 easeOutExpo 缓动从 0 滚到 12800,每三位加千分位,用 requestAnimationFrame 按时间戳算进度,不要用 setInterval。容器用 font-variant-numeric: tabular-nums 并预留宽度,避免位数变化时抖动;系统开启减少动态效果时直接显示 12800。

什么时候用

  • 数据面板的关键指标第一次出现,想让数字有涨上去的感觉
  • 首屏用一两个大数字当主角,给一个短促的入场
  • 想让数字滚动在进入视口后再开始,而不是页面一打开就已经跳完

适用场景:页面 / 卡片 / 列表

推荐取值

时长
800–1500ms
缓动
easeOutExpo / easeOutCubic
数字排版
font-variant-numeric: tabular-nums
触发
IntersectionObserver,threshold 0.3
终值停留
滚完至少 300ms 不再变化

别搞混

  • 和「机械翻牌 odometer」的区别

    odometer 是每一位数字上下滚动或翻页,位与位之间有物理位移;数字滚动只是数值在变,字形本身不动。

  • 和「CSS @property 数值动画」的区别

    @property 可以注册一个整数自定义属性再交给 counter() 渲染,纯 CSS 就能跑,但插值交给浏览器,格式和缓动不好控;要精确控制格式、缓动和重播,用 requestAnimationFrame 手写更稳。

容易踩的坑

  • 位数变化会撑动布局(9 变 10、99 变 100),给容器预留宽度,并用 font-variant-numeric: tabular-nums 让每位数字等宽。
  • requestAnimationFrame 循环要在组件卸载时 cancel,否则组件没了还在 setState。
  • rAF 回调拿到的是高精度时间戳,用它减去开始时间;不要和 Date.now() 混算,也不要拿 setInterval 每帧加固定值,掉帧时会越走越慢。
  • 服务端渲染和首次客户端渲染必须渲染同一个值(通常是 0),否则 hydration 对不上;挂载之后再开始跑。
  • prefers-reduced-motion 下直接显示最终值,别让数字再滚一遍。

无障碍降级

prefers-reduced-motion: reduce 时不跑帧循环,直接把目标值一次性渲染出来。

关键词

  • requestAnimationFrame
  • tabular-nums
  • font-variant-numeric
  • easeOutExpo
  • count up animation
  • IntersectionObserver

参考

相关展品