数字滚动统计条
Animated Stats Counter
初级通用官网往下滚到「用数字说话」那一段时,几个统计数字从 0 飞快地数到目标值,然后稳稳停住。「12,800+ 用户」「98.6% 好评」这类数字,数起来比直接摆着更有说服力。
你可能会说:「官网上「多少用户、多少好评」那几个数字,能不能滚到的时候从 0 数上去?」
效果预览滚到时数字从 0 数上去
正在加载演示…
怎么做3 步做出来
- 1
目标值写在 data 属性里
把最终数字写在 data-target 上,页面上先显示 0。读屏软件读到的应该是最终值,所以另放一份对读屏可见的完整文字,动画中的数字对读屏隐藏。
查看代码收起代码html
<div class="stats"> <div class="stat"> <b class="stat__num" data-target="12800" data-suffix="+" aria-hidden="true">0</b> <span class="sr-only">注册用户 12,800+</span> <span aria-hidden="true">注册用户</span> </div> <div class="stat"> <b class="stat__num" data-target="98.6" data-decimals="1" data-suffix="%" aria-hidden="true">0</b> <span class="sr-only">好评率 98.6%</span> <span aria-hidden="true">好评率</span> </div> </div> - 2
等宽数字,避免抖动
大多数字体里 1 比 8 窄,数字一滚整行就左右抖。tabular-nums 让每一位都一样宽。
查看代码收起代码css
.stat__num { font-size: 2rem; font-weight: 900; font-variant-numeric: tabular-nums; } .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; } - 3
进入视野时数一次
用 IntersectionObserver 等统计条出现再开始,只数一次。每一帧按「已过时间 ÷ 总时长」算进度,再用减速曲线让数字越接近终点走得越慢,最后稳稳停住;每一帧都按最终格式(千分位、小数位)显示。开启减少动效时直接显示最终值。
查看代码收起代码js
const DURATION = 1600; const easeOut = (t) => 1 - Math.pow(1 - t, 3); const reduced = matchMedia('(prefers-reduced-motion: reduce)').matches; function countUp(el) { const target = Number(el.dataset.target); const decimals = Number(el.dataset.decimals || 0); const suffix = el.dataset.suffix || ''; const format = (n) => n.toLocaleString('zh-CN', { minimumFractionDigits: decimals, maximumFractionDigits: decimals, }) + suffix; if (reduced) return (el.textContent = format(target)); const start = performance.now(); const tick = (now) => { const t = Math.min(1, (now - start) / DURATION); el.textContent = format(target * easeOut(t)); if (t < 1) requestAnimationFrame(tick); }; requestAnimationFrame(tick); } const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (!entry.isIntersecting) return; entry.target.querySelectorAll('.stat__num').forEach(countUp); observer.unobserve(entry.target); }); }, { threshold: 0.6 }); document.querySelectorAll('.stats').forEach((el) => observer.observe(el));
适合放在哪
适合用
- 官网「用户数、好评率、服务客户数」这类成绩展示。
- 年度报告、活动战报页里的关键数字。
- 课程或产品详情页的「已有多少人学习」。
不适合用
- 后台看板这种用户要立刻读准数字的地方,别每次都从 0 数;直接显示,或从旧值过渡到新值。
- 数字很小(比如 3、5)时,数起来没意义;直接显示。
- 一屏里有十几个数字时,别全都滚;挑最重要的三四个。
让 AI 帮你做复制给 AI Agent 直接用
请给【官网的统计数字区域,如:首页「用数字说话」那一栏】加上数字滚动效果。先阅读这个区域的组件和数据来源,确认数字、单位和小数位从哪里来。要求:用 IntersectionObserver 在区域进入视野约 60% 时开始,只播一次;1.2~2 秒内从 0 数到目标值,用减速缓动;每一帧都按最终格式显示(千分位、小数位、后缀单位);数字使用 tabular-nums 等宽字形;动画中的数字对读屏隐藏,另提供完整的最终文字;开启减少动效时直接显示最终值;组件卸载时取消动画帧。沿用现有写法,不改无关代码。最后说明怎样验证:滚到该区域时只数一次,读屏读到的是最终值。