最简滚动公告可用标签实现,但因废弃、兼容性差、无障碍缺失而不推荐生产使用;推荐用CSS @keyframes动画配合transform: translateX()模拟滚动,并通过JavaScript添加悬停暂停等交互功能。

用 <marquee></marquee> 实现最简滚动公告(但别在生产环境用)
直接上手最快的方式是用原生 <marquee></marquee> 标签,比如:
<marquee behavior="scroll" direction="left" scrollamount="3">紧急通知:系统将于今晚22:00维护</marquee>它支持
direction(left/right/up/down)、scrollamount(步长)、scrolldelay(毫秒级延迟)等属性。但要注意:<marquee></marquee> 是废弃标签,Chrome/Firefox 已不保证行为一致,Safari 甚至默认禁用;无障碍支持为零;无法用 CSS 精确控制暂停、加速或响应式缩放。
用 CSS @keyframes + animation 替代(推荐)
真正可靠的做法是用纯 CSS 动画模拟滚动。核心思路是让容器宽度超限,再用 transform: translateX() 水平位移:
<div class="notice-bar"> <div class="notice-content">? 新版 App 已上线|⏰ 活动倒计时:3天|✅ 订单满299包邮</div> </div>
对应 CSS:
.notice-bar {
overflow: hidden;
white-space: nowrap;
}
.notice-content {
display: inline-block;
animation: scroll-left 20s linear infinite;
}
@keyframes scroll-left {
0% { transform: translateX(100%); }
100% { transform: translateX(-100%); }
}
关键点:
立即学习“前端免费学习笔记(深入)”;
-
animation-duration越大,滚动越慢;建议设为 15–30s,太短会眼花,太长显得卡顿 - 必须加
white-space: nowrap防止文字换行打断滚动流 - 若内容含图标或 emoji,确保字体支持(如用
system-ui, "Segoe UI"),否则可能错位 - 移动端需加
will-change: transform提升动画性能
用 JavaScript 控制暂停/鼠标悬停交互
纯 CSS 方案无法响应用户操作,需要暂停时就得加 JS。监听 mouseenter 和 mouseleave 即可:
const bar = document.querySelector('.notice-bar');
bar.addEventListener('mouseenter', () => {
bar.style.animationPlayState = 'paused';
});
bar.addEventListener('mouseleave', () => {
bar.style.animationPlayState = 'running';
});
注意:
- 不要用
classList.toggle()切换动画类名——重排会导致跳帧 - 如果页面有多个滚动栏,避免用全局
querySelector,改用this或 data 属性定位 - 若需键盘焦点支持(如屏幕阅读器),得额外加
tabindex="0"和keydown监听空格/Enter 键
滚动内容过长或动态更新时的处理
当公告条目多、需轮播或后端实时推送时,CSS 动画方案会暴露局限:
- 单行拼接所有文案易造成 DOM 过宽,尤其在小屏设备上触发横向滚动条
- 新增一条公告时,直接修改
innerText会重置动画,出现“闪回” - 无法实现“逐条淡入+滑入”的更友好动效
这时建议用轻量 JS 库(如 marquee.js)或自己封装一个双容器轮播逻辑:用两个 <div> 并排,动画结束时把第一个内容移到末尾并重置位置,视觉上无缝。但多数内部公告场景,CSS 方案已足够——别为了“看起来高级”提前引入复杂度。
<p>真正容易被忽略的是:滚动速度要匹配文字长度。10 个字和 50 个字用同一个 <code>20s 动画,前者像散步,后者像狂奔。上线前务必在手机真机测三遍。



















