纯CSS双份内容方案最可靠,通过flex布局与@keyframes实现无闪烁横向无限滚动,关键在于位移精度、接缝对齐、linear动画及真机验证。

纯 CSS 就能实现稳定、无闪烁的横向无限循环滚动,关键不是“怎么动”,而是位移精度和接缝处理——flex双份内容方案最可靠,JS 方案容易在 tab 切换后掉帧或跳图。
为什么用双份内容而不是 JS 动态移动
常见错误是写个 setInterval 不停改 scrollLeft 或 transform,结果弱网下卡顿、iOS 后台切回来白屏、动画中断时露出空白。而双份内容靠 CSS @keyframes 做匀速位移,浏览器原生合成,不依赖 JS 执行时机。
- 接缝必须自然:第二份内容起始位置要和第一份结尾完全对齐,不能靠 JS 补偿
- 动画必须
linear:用ease会导致中间快、两头慢,接缝处一卡就露馅 - 位移终点必须等于原始内容总宽(含
margin、padding):差 1px 都会错位
HTML 结构怎么写才不出错
不是简单复制 DOM 节点就行——顺序、包裹层级、是否带空格都会影响 flex 计算宽度。
- 把所有
.scroll-item写两遍,中间**不能有换行或空格文本节点**,否则white-space: nowrap也拦不住额外空隙 - 外层容器用
display: flex,但**不要加flex-wrap: nowrap**(默认就是),加了反而可能干扰 - 每个
.scroll-item必须设flex-shrink: 0和显式width(比如width: 200px),否则 flex 会压缩总宽导致位移不准 - 如果子项含图片,记得加
min-width: 0防止 img 撑破布局
CSS 动画参数怎么算才精准
位移值不是凭感觉写的,必须严格按渲染后尺寸计算。例如三张卡片,每张 width: 200px,左右 margin: 20px,那总宽 = 3 * 200 + 2 * 20 = 640px。
立即学习“前端免费学习笔记(深入)”;
-
@keyframes scroll的终点必须是transform: translateX(-640px),不能写-100%或-100vw - 动画时长建议 ≥ 3s:太短人眼易察觉接缝;太长滚动感弱,尤其内容少时
- 外层容器必须设
overflow: hidden,否则位移过程中边缘会漏出副本开头或空白底色 - 如果用了
gap,要把它换算进总宽——gap是 flex 新增属性,老浏览器不支持,建议用margin-right控制间距
移动端和 Safari 的兼容性陷阱
看似简单的 flex + animation,在 iOS Safari 上常因渲染优化被“冻结”:切到后台再切回来,动画暂停、卡死、甚至直接跳到终点。
- 加
will-change: transform到滚动容器上,强制开启 GPU 合成 - 避免在动画中同时改
transform和opacity,Safari 容易丢帧 - 别用
translate3d(0, 0, 0)强升 GPU——现代浏览器已自动优化,反而增加内存开销 - 如果内容动态加载,务必等所有
.scroll-item渲染完成后再启动动画,否则初始宽度算错
真正难的不是写出第一版能动的代码,而是让接缝在 1080p 屏上肉眼不可见、在低端安卓机上不掉帧、在 Safari 切后台后能无缝续播——这些细节全靠像素级测量和真机反复验证。



















