最稳妥方案是用@keyframes+animation实现滚动,因<marquee>已废弃、无标准支持、行为不一致且无法响应式控制;核心是transform: translateX()配合双份内容与无缝衔接,需注意white-space、padding-left及hover暂停写法。

直接用 @keyframes + animation 实现最稳妥,marquee 标签已废弃且不兼容现代浏览器。
为什么不用 <marquee>
这个 HTML 标签在所有现代浏览器中都只是“勉强渲染”,没有标准支持,direction、behavior 等属性行为不一致,Chrome 甚至会报 marquee is deprecated 警告。更关键的是它无法响应式控制、不能和 CSS 变量联动、动画暂停/加速也无从下手。
实际项目中一旦需要适配移动端或配合 JS 控制滚动节奏,立刻卡死。
transform: translateX() 滚动的核心写法
本质是让文字容器在水平方向做位移动画,通过无限循环 + 无缝衔接(内容复制)模拟滚动效果。关键在于两点:动画终点要回到起点,且容器宽度足够容纳双份内容。
立即学习“前端免费学习笔记(深入)”;
示例结构:
.notice-bar {
white-space: nowrap;
overflow: hidden;
}
.notice-bar span {
display: inline-block;
padding-left: 100%;
animation: scroll 20s linear infinite;
}
@keyframes scroll {
0% { transform: translateX(0); }
100% { transform: translateX(-100%); }
}
注意点:
-
padding-left: 100%是为了让第二份文案从右侧开始,实现视觉无缝 —— 不是靠 margin 或 width - 动画时长
20s要根据文案长度动态调整;太短会快得看不清,太长则显得呆滞 - 必须设
white-space: nowrap,否则换行会打断滚动流 - 如果父容器有
text-align: center,需额外加text-align: left到span上,避免居中干扰位移基准
如何暂停鼠标悬停时的滚动
直接用 :hover 控制 animation-play-state 即可,但要注意作用对象 —— 必须加在触发元素(如 .notice-bar)上,且动画定义本身要在子元素(如 span)上:
.notice-bar:hover span {
animation-play-state: paused;
}
常见错误:
- 写成
.notice-bar:hover { animation-play-state: paused }→ 无效,因为动画不在父元素上 - 用
display: none或visibility: hidden暂停 → 会重置动画状态,恢复时从头开始 - 没考虑触摸设备,应补充
@media (hover: hover)条件或同时监听touchstart事件
多行公告 & 响应式适配要点
单行滚动容易,但业务常要求“多条消息逐条上浮”或“横滚+纵滚混合”。此时不要硬套 translateX,改用 transform: translateY() + height 控制更可控。
例如三行轮播:
.notice-list {
height: 40px;
overflow: hidden;
}
.notice-list li {
height: 40px;
line-height: 40px;
animation: slide-up 9s infinite;
}
.notice-list li:nth-child(1) { animation-delay: 0s; }
.notice-list li:nth-child(2) { animation-delay: 3s; }
.notice-list li:nth-child(3) { animation-delay: 6s; }
@keyframes slide-up {
0% { transform: translateY(0); }
33% { transform: translateY(-40px); }
66% { transform: translateY(-80px); }
100% { transform: translateY(0); }
}
响应式重点:
- 移动端建议把动画时长放大 1.5 倍(如
30s),小屏下人眼追踪更慢 - 字体缩放后,
line-height和height必须同步用em或rem,否则错位 - 避免在
@media中重复定义整个@keyframes,改用 CSS 变量控制时长和位移值更轻量
真正难的不是写出来,而是让滚动速度、暂停逻辑、多端表现、JS 动态注入新公告这四者不互相打架 —— 建议把动画控制权收归一个 requestAnimationFrame 循环,而不是全靠 CSS 声明式驱动。


















