真正能上线的滚动字幕必须用 css 或 js 实现,禁用已废弃的 ;css 方案推荐 @keyframes + transform: translatex() 实现高性能无缝滚动,js 方案需用 requestanimationframe 并兼顾可访问性与响应式。

用 <marquee></marquee> 实现滚动字幕,但别真用它
浏览器早就废弃 <marquee></marquee> 了。Chrome、Firefox、Edge 默认不渲染,Safari 直接忽略,控制台还会报 Deprecated API usage。它不是“还能凑合”,而是“随时可能彻底失效”。真正能上线的滚动文字,必须用 CSS 或 JS 实现。
CSS @keyframes 滚动最稳妥
现代方案里,纯 CSS 实现滚动字幕兼容性好、性能高、语义清晰。核心是用 transform: translateX() 配合动画,避免重排。
常见错误现象:
– 文字闪一下才开始动(没设初始 transform)
– 滚动到头卡住或跳回(没用 infinite 或循环逻辑没对齐)
– 在移动端卡顿(用了 left 或 margin-left 触发重排)
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 容器设
overflow: hidden,子元素宽度要大于容器(比如width: max-content或明确设宽) - 动画关键帧从
translateX(100%)到translateX(-100%),确保无缝衔接 - 用
animation-timing-function: linear,避免缓动导致速度不均 - 加
will-change: transform提前提示 GPU 加速(小字幕可省,长文本建议加)
简短示例:
.marquee {
overflow: hidden;
white-space: nowrap;
}
.marquee span {
display: inline-block;
animation: scroll 20s linear infinite;
will-change: transform;
}
@keyframes scroll {
0% { transform: translateX(100%); }
100% { transform: translateX(-100%); }
}
JS 控制滚动更灵活,但也更容易出问题
需要暂停/播放/变速/点击跳转时,JS 是唯一选择。但多数人直接用 setInterval + scrollLeft,结果在低帧率设备上卡顿、不同步、内存泄漏。
使用场景:
– 新闻跑马灯需鼠标悬停暂停
– 多行滚动且每行速度不同
– 数据动态更新后重置滚动位置
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 用
requestAnimationFrame替代setInterval,帧率更稳 - 避免频繁读写
scrollLeft,改用transform移动内部容器 - 暂停时清除 rAF ID,恢复时重新启动,别靠
clearInterval补救 - 滚动结束位置计算要基于文字真实宽度(
getBoundingClientRect().width),别硬写像素值
移动端适配和可访问性常被忽略
滚动字幕在手机上默认会被缩放、截断、甚至触发强制横向滚动条。更关键的是,屏幕阅读器会把滚动文字反复朗读,造成干扰。
参数差异与影响:
-
aria-hidden="true"必须加在滚动容器上,否则视障用户听到一堆无意义重复文本 - 用
prefers-reduced-motion: reduce媒体查询检测用户是否开启“减少运动”,此时应静止显示或改为淡入淡出 - 字体大小用
rem或em,别用固定px,否则 iOS 缩放后文字溢出容器 - 不要给滚动区域设
touch-action: none,否则 iOS 上无法双指缩放页面
复杂点不在怎么滚,而在什么时候不该滚——用户没看到、不需要看、或者根本没法看清的时候,滚动本身就是 bug。











