
本文详解如何通过纯 CSS 构建真正无缝的无限滚动轮播(marquee),解决传统 left 百分比动画导致的循环跳变问题,核心在于用 transform: translateX() 替代 left,并精确计算容器宽度以匹配内容尺寸。
本文详解如何通过纯 css 构建真正无缝的无限滚动轮播(marquee),解决传统 `left` 百分比动画导致的循环跳变问题,核心在于用 `transform: translatex()` 替代 `left`,并精确计算容器宽度以匹配内容尺寸。
实现平滑无限滚动的关键,在于消除动画终点与起点之间的视觉断层。原代码中使用 position: absolute + left: -100% 存在两个根本性缺陷:
-
left: -100%的基准是父容器宽度,而非实际内容宽度,导致位移不足或过度; -
width: 200%是相对父容器计算的,无法准确容纳所有.marquee-item及其gap,造成布局挤压或溢出。
✅ 正确解法是:
-
用
transform: translateX()替代left:transform中的百分比基于元素自身宽度,-100%即精准向左移动一个完整内容宽度,动画更可控且硬件加速性能更优; -
显式计算
.marquee-inner总宽度:避免依赖模糊的百分比,直接按item 宽度 + gap× 数量 + 首尾 gap 补偿,确保内容完全展开。
以下是优化后的核心 CSS(关键修改已高亮):
.marquee-inner {
display: flex;
/* ✅ 精确计算总宽度:每个 item 580px + 40px gap,共 --total-marquee-items 个,末尾额外 +40px gap */
width: calc((580px + 40px) * var(--total-marquee-items) + 40px);
position: absolute;
}
@keyframes marqueeLeft {
0% {
transform: translateX(0); /* 起点:内容完全可见 */
}
100% {
transform: translateX(-100%); /* 终点:向左平移自身 100%,即无缝衔接下一组 */
}
}
@keyframes marqueeRight {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(0);
}
}? HTML 结构注意事项:
立即学习“前端免费学习笔记(深入)”;
- 必须为
.marquee-inner内提供至少两组重复内容(如<span></span>包裹两套 1–5),这是实现“视觉无缝”的基础——当第一组滑出视口时,第二组恰好补位; -
.marquee-block的overflow: hidden是裁剪边界,确保只显示当前滚动区域; - 所有
.marquee-item保持固定宽580px,与 CSS 中的计算值严格一致,避免因渲染差异引发微小错位。
⚠️ 进阶提示:消除最后一帧“停顿感”
即使使用 transform,标准 0% → 100% 动画仍存在理论上的帧重叠(首尾状态相同)。若对流畅度要求极高,可采用「负延迟偏移」技巧:将动画周期微调为 99.9%,或使用 animation-timing-function: steps() 分段控制——但本方案已满足绝大多数场景的工业级平滑需求,且完全零 JS、响应式无关、无媒体查询干扰。
最终效果:轮播内容以恒定速度持续滚动,循环切换毫无感知,完美契合设计系统对优雅交互动效的要求。


















