最轻量纯CSS横向无限滚动方案是用@keyframes+translateX实现,核心为容器位移自身总宽后无缝循环,需配合white-space:nowrap、overflow:hidden、vertical-align:top及GPU加速优化。

用 CSS @keyframes + animation 实现横向无限滚动
纯 CSS 方案最轻量,适合静态图片序列,不依赖 JS。核心是让图片容器在水平方向位移一个自身宽度后回到起点,形成视觉循环。
关键点在于:容器需设为 display: inline-block 或使用 white-space: nowrap 防止换行;动画位移值必须精确匹配图片总宽度(含间隙),否则会出现跳帧或停顿。
- 图片用
<img>放入<div class="scroller">,该 div 设overflow: hidden - 内部包裹层(如
<div class="scroller-inner">)设white-space: nowrap,所有<img>设vertical-align: top消除基线间隙 - 动画从
transform: translateX(0)到translateX(-Wpx),其中W是所有图片宽度 + 间距之和 - 用
animation: scroll 20s linear infinite,时长越长滚动越慢;infinite是循环关键
@keyframes scroll {
0% { transform: translateX(0); }
100% { transform: translateX(-600px); } /* 假设总宽600px */
}
.scroller-inner {
animation: scroll 25s linear infinite;
}为什么不能直接用 background-image + background-position 滚动?
背景图滚动看似简单,但无法真正“无限”——它只能平铺(repeat),而平铺的衔接点在像素边界,一旦图片本身有渐变、阴影或非整像素边框,接缝就会露馅。更麻烦的是,background-position 动画无法自动适配不同屏幕宽度下的实际渲染尺寸,缩放后位移计算会失准。
- 响应式场景下,
vw单位用于background-position会导致动画速度随视口变化,难以控制节奏 - 如果图片需点击跳转或添加
alt文本,<img>是唯一语义正确且可访问的选择 - 部分安卓 WebView 对
background-position动画的硬件加速支持差,容易卡顿
用 JavaScript 补齐响应式重算与暂停交互
CSS 动画写死时长和位移后,窗口缩放时图片实际宽度变了,但动画仍按旧值跑,导致错位或加速。JS 的作用不是主导滚动,而是监听 resize 后重置 animation-duration 和关键帧位移值。
立即学习“前端免费学习笔记(深入)”;
- 用
getBoundingClientRect().width动态读取.scroller-inner当前总宽,而非靠 JS 计算每张图尺寸 - 修改
style.animationDuration保持视觉速度一致(例如始终维持 1px/ms) - 鼠标悬停时设
animation-play-state: paused,离开恢复,避免用户想看清时还在滑 - 慎用
requestAnimationFrame自驱动滚动——它在后台标签页会被节流,反而造成不一致
移动端 Safari 上 transform: translateX 卡顿怎么办?
iOS Safari 对非 transform + opacity 属性的动画默认不启用 GPU 加速,translateX 理论上已满足,但若父容器有 overflow: hidden 且高度不定,仍可能触发软件渲染。
- 强制开启 GPU:给滚动容器加
transform: translateZ(0)或will-change: transform - 确保所有图片设明确
height(哪怕用aspect-ratio),避免重排引发动画中断 - 不要在滚动容器上用
filter(如blur)、box-shadow或border-radius,这些会破坏合成层 - 真机测试时打开 Safari 开发者工具 → “Timelines” 面板,看是否持续跑在 60fps —— 卡顿往往不是代码问题,而是某张图片解码耗时太久
最常被忽略的是图片格式和尺寸:用 webp 替代 png,宽度控制在 1200px 以内,不然 iOS 解码压力会直接拖垮动画帧率。



















