走马灯这个效果,说大不大,说小也不小。说它不大,是因为很多项目的“公告栏”“消息条”就是一行字在那里滚,看着很简单;说它不小,是因为真要做得顺滑、不闪烁、不跳变、还能适配各种场景,纯靠CSS写和靠一套成熟方案写,差距非常大。我这两年在前端项目里接触过不少类似需求,像是后台数据大屏的跑马通知、活动页的标语滚动、还有长列表的横向轮播展示,纯CSS都能扛住大部分场景,而且相比引入一个跑马灯插件或者写一堆JS逻辑,纯CSS的方案更轻、更快、也更好维护。换句话说,如果你要做的不是那种带复杂交互(比如鼠标拖动、点击左右箭头分页)的轮播,只是想让内容自动滚动起来,那用CSS实现走马灯是完全够用的。
这篇文章我就按自己实际做过的项目经验,把纯CSS实现走马灯的几种思路、原理、坑点,还有不同场景下的选型建议都整理出来。不管你是刚接触CSS动画的新手,还是已经在项目里写过几轮轮播但总觉得不够顺滑的开发者,这篇文章都能给你一套可以直接抄作业的方案,以及一些常规文档里不会写明白的细节。
1. 需求场景与方案选型:你真的需要走马灯吗
1.1 走马灯在项目里到底解决什么问题
走马灯的经典应用场景很多,比如后台管理页顶部的“系统公告”、官网首页的“最新动态”、大屏项目里的“实时数据播报”,甚至一些页面的“合作伙伴Logo墙”也会用横向滚动来展示。这类场景有一个共同点:信息量超过容器宽度,但又不希望用户手动操作,这时候让内容自动滚动起来,是成本最低的展示方式。
我见过不少团队在做这类需求时,第一反应是去npm搜一个轮播插件,或者自己写一段setInterval配合DOM操作的逻辑。但说实话,很多走马灯需求根本不涉及分页、索引、导航按钮这些复杂交互,就是“让内容动起来”。在这种前提下,引入插件或编写大量JS不仅增加了维护成本,还可能在性能上踩坑——因为用JS频繁操作DOM的left/top属性,会引发布局抖动,尤其是在低端移动设备上,掉帧非常明显。
另一个常见的误区是用<marquee>标签。这个标签虽然能实现简单的滚动效果,但它已经被标准移除,行为在各浏览器里并不一致,而且没法做精细控制,比如无缝衔接、暂停、反向、速度调节都要靠各种hack,非常别扭。所以现在的主流方案,就是用CSS动画来驱动。
1.2 纯CSS方案相比JS方案的优势在哪里
纯CSS走马灯最大的优势是动画过程由浏览器合成器直接处理。你只需要定义一个关键帧动画,浏览器通常会把transform属性优化到合成线程执行,不会反复触发主线程的布局和绘制,因此即使长时间运行也不容易卡顿。
这里举一个具体的对比。用JS写的话,每16毫秒你就要手动更新一次元素位置(requestAnimationFrame),还要考虑时间步长、边界判断、页面隐藏时暂停等一堆边界问题;而CSS只需要写一句animation,浏览器会帮你处理时间、帧率、暂停恢复这些细节。哪怕你把动画时长设置成30秒、60秒,它也不会出现计时漂移,这一点是setInterval很难做到的。
纯CSS还有个潜在优势:无依赖、无运行时逻辑。如果你的页面还有其他重交互,减少主线程负担对整体体验是有帮助的。而且从维护角度看,纯CSS的代码量通常只有十几行到几十行,后续改速度、改方向、改样式都非常直观。
这么说并不是要否定JS方案。如果你的需求是“根据用户手势来控制滚动速度”“根据数据的长度动态调整动画时长”“点击每个滚动项要弹出不同内容”,那主逻辑肯定要放在JS里,CSS只承担渲染部分。但如果需求是“内容自动滚动,最好能无缝循环”,那我会毫不犹豫选纯CSS。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从一个最简版本说起:CSS动画的基础模型
2.1 用animation + transform实现横向位移
实现走马灯最核心的动作就是“移动”。传统的写法是让元素从left: 0移动到left: -100%,但更推荐的做法是用transform: translateX()。理由后面会细说,这里先看一个最简单的demo,这种写法适合做“一次性滚动到头,然后跳回来”的简单公告。
html复制<div class="marquee">
<span class="marquee-text">这是一条公告:系统将于今晚22点进行例行维护,请提前保存数据。</span>
</div>
css复制.marquee {
width: 100%;
overflow: hidden;
white-space: nowrap;
background: #f5f5f5;
padding: 10px 0;
}
.marque
