纯css无限循环滚动是视觉欺骗,依赖动画与内容复用;需用transform而非margin-top以避免重排,双列表拼接消除跳动,终点值须设为单份高度且子项高度必须一致。

纯 CSS 实现的“无限循环滚动”本质是视觉欺骗,不是真无限加载——它靠动画 + 内容复用撑起循环感。性能高,但只适合内容静态或低频更新的场景(比如公告栏、行情跑马灯)。真要动态加载新数据,必须加 JS。
为什么 transform: translateY() 比 margin-top 更适合滚动动画
关键在渲染层:transform 触发 GPU 合成,不触发 layout 和 paint;margin-top 会强制重排(reflow),列表越长卡顿越明显。
- 动画帧率稳定在 60fps 的前提是避免主线程阻塞,
transform是目前最轻量的位移方式 -
will-change: transform可提前提示浏览器做图层提升,但别滥用——只对长期动画的元素加 - 不要用
top+position: relative/absolute做滚动,它同样触发重排,且受父容器 stacking context 影响更隐蔽
@keyframes 中的终点值必须等于列表总高度
留白的根本原因,90% 出在这里:动画终点设成固定像素(如 translateY(-500px)),但列表实际高度随内容增减而变。
- 正确做法是用百分比:
100%指的是.scroll-list自身高度,不是容器高度 - 必须确保
.scroll-list高度可被精确计算:所有子项用固定高度,或用display: flex; flex-direction: column;+height: fit-content配合 JS 动态写入 - 如果子项高度不一致,CSS 动画无法自适应——此时别硬上纯 CSS 方案,改用虚拟滚动 + JS 控制
transform
用双列表拼接消除重置跳动
单列表动画播完一周期后跳回起点,人眼能感知到“闪”。解决方案是准备两份相同内容,并让它们首尾相接,动画距离设为单份高度。
- HTML 结构要这样写:
- item 1
- item 2
- item 3
- item 1
- item 2
- item 3
- CSS 动画终点设为
translateY(-<em>单份高度</em>),而不是-<em>总高度</em> - 动画时长按可视区域高度 / 滚动速度算,别凭感觉设 5s 或 10s——速度太快看不清,太慢显得卡顿
真正难的不是写动画,而是让“复制品”的 DOM 与原始项完全一致:字体渲染、行高、边框盒模型、甚至 subpixel 渲染都要对齐。稍有偏差,循环点就会出现半像素错位。这一步没法靠 CSS 自动解决,得靠开发者盯着 DevTools 的 Layers 面板逐项比对。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











