
本文介绍一种基于 CSS @keyframes 和 transform: translateX() 的纯 CSS 无限横向滚动方案,彻底替代 jQuery 动画+DOM 操作的低效实现,解决跳动、卡顿问题,并支持悬停暂停,性能更优、代码更简洁。
本文介绍一种基于 css `@keyframes` 和 `transform: translatex()` 的纯 css 无限横向滚动方案,彻底替代 jquery 动画+dom 操作的低效实现,解决跳动、卡顿问题,并支持悬停暂停,性能更优、代码更简洁。
传统 JavaScript 驱动的跑马灯(如使用 setInterval + animate() 修改 marginLeft 并动态移动 DOM 节点)存在多个根本性缺陷:动画帧率不稳定、布局重排频繁、DOM 操作引发回流、暂停/恢复时状态不同步——这些正是导致“轻微跳动”的核心原因。
推荐方案:纯 CSS 实现平滑无限滚动
✅ 优势显著:
- 利用 GPU 加速的
transform属性,渲染性能远高于margin或left; - 避免 JavaScript 定时器与 DOM 操作,消除帧抖动与重排开销;
- 悬停控制仅需
animation-play-state: paused,响应即时无延迟; - 语义清晰、可维护性强,无需手动计算宽度或偏移量。
✅ 核心 CSS 实现
.marquestarthere {
display: flex;
gap: 56px 31px;
animation: 8s marquee linear infinite;
/* 关键:禁用换行,确保单行滚动 */
flex-wrap: nowrap;
/* 可选:隐藏溢出内容,保持视觉整洁 */
overflow: hidden;
}
.marquestarthere:hover {
animation-play-state: paused;
}
@keyframes marquee {
0%, 100% {
transform: translateX(0);
}
99.999% {
transform: translateX(-50%);
}
}
? 为什么是
translateX(-50%)?
因为我们将原始列表项完整复制一份(见下方 HTML 结构),使总内容宽度 ≈ 200%。当动画从0%运行到99.999%时,元素向左平移自身总宽度的一半,恰好让第二组内容无缝接替第一组——人眼感知为“无限循环”,且无突兀重置。
✅ HTML 结构要点:双倍内容 + 无 JS 干预
在 <ul class="marquestarthere"></ul> 中,将全部 .marqueme 元素完整复制一次(即 6 项 → 12 项),无需任何 JavaScript 初始化或 DOM 操作:
- ...
- ...
- ...
- ...
⚠️ 注意事项:
- 不要删减副本数量:副本必须与原数组完全一致且顺序相同,否则衔接处会出现空白或错位;
-
避免设置
width: max-content在容器上:它可能干扰 flex 容器的自然伸展,建议移除或改用min-width: fit-content; -
确保子项不换行:
.marqueslide .marqueme { flex: 0 0 auto; }已正确,但需确认无flex-wrap: wrap等干扰; -
移动端兼容性:现代浏览器均支持
animation-play-state;若需兼容旧版 iOS Safari(-webkit-animation-play-state 前缀。
✅ 进阶优化建议(可选)
-
自适应速度:将
8s改为 CSS 自定义属性,便于全局调控:.marquestarthere { --marquee-duration: 10s; animation: var(--marquee-duration) marquee linear infinite; } -
反向滚动:修改
@keyframes中translateX为正值,并调整方向逻辑; -
响应式适配:结合
@media动态调整--marquee-duration或gap,保证小屏下滚动节奏舒适。
总结:抛弃 jQuery 动画+DOM 搬运的老套路,拥抱声明式、硬件加速的 CSS 动画方案,不仅能彻底根治“跳动”问题,还能显著降低代码复杂度与运行时开销。只需复制内容、写几行 CSS,即可获得专业级平滑跑马灯体验。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











