不推荐使用marquee标签,HTML5已废弃;应采用CSS动画或JavaScript实现滚动,前者轻量高效,后者更灵活可控。

滚动文字用 marquee 标签还行吗?
不行。HTML5 已废弃 marquee,现代浏览器虽多数仍能渲染,但不保证兼容性,且无法精准控制速度、暂停、方向等行为。W3C 明确不推荐,CSS 动画或 JavaScript 才是正解。
用 CSS @keyframes + animation 实现批量滚动
这是最轻量、性能最好、也最容易批量生成的方式。核心思路是:用 JS 拼接 HTML 字符串(模板字符串),插入容器,再靠 CSS 统一驱动滚动动画。
- 滚动容器必须设
white-space: nowrap和固定宽度/溢出隐藏 - 每个滚动项需包裹在独立
<span>或<div>中,并设display: inline-block避免换行挤压 - 动画时长和延迟要根据文字长度动态计算,否则短文本会“闪退”,长文本会卡顿
const texts = ['前端开发', 'React 19', 'TypeScript 5.4', 'Vite 5'];
const container = document.getElementById('ticker');
const html = texts.map((text, i) => `
<span class="ticker-item" style="--delay: ${i * 2}s;">${text}</span>
`).join('');
container.innerHTML = html;CSS 部分需配合:
@keyframes ticker-move {
0% { transform: translateX(100%); }
100% { transform: translateX(-100%); }
}
.ticker-item {
display: inline-block;
margin-right: 2rem;
animation: ticker-move 15s linear infinite;
animation-delay: var(--delay);
}用 requestAnimationFrame 手动滚动更可控
当需要响应鼠标悬停暂停、点击跳转、或与滚动位置联动时,CSS 方案不够灵活。此时应改用 JS 控制位移,模板字符串依然用于初始 DOM 插入,但后续靠帧循环更新 transform。
立即学习“前端免费学习笔记(深入)”;
- 避免直接操作
scrollLeft—— 容器需设overflow: hidden,否则滚动条干扰布局 - 每帧位移量建议用时间差(
deltaTime)计算,而非固定像素,防止高刷屏下加速 - 批量生成后,对每个
ticker-item保存其起始offsetWidth,用于判断是否移出视区并复位
关键逻辑节选:
let x = 0;
function tick(timestamp) {
if (!lastTime) lastTime = timestamp;
const deltaTime = timestamp - lastTime;
x -= deltaTime * 0.2; // 像素/ms 调速
items.forEach(el => el.style.transform = `translateX(${x}px)`);
if (x < -totalWidth) x = 0; // 复位
requestAnimationFrame(tick);
}模板字符串拼接 DOM 的坑:别漏了 textContent 转义
如果滚动内容来自用户输入或 API,直接插进模板字符串会引发 XSS。比如 ${userInput} 遇到 <script>alert(1)</script> 就执行了。
- 安全做法:先创建临时元素,用
textContent赋值,再取innerHTML - 或用
DOMPurify.sanitize()过滤,但会增加包体积 - 纯文字滚动场景下,优先用
document.createTextNode()替代字符串插值
简易转义函数示例:
function escapeHtml(str) {
const div = document.createElement('div');
div.textContent = str;
return div.innerHTML;
}
const safeText = escapeHtml(userInput);
const itemHtml = `<span class="ticker-item">${safeText}</span>`;批量生成滚动文字本身不难,难的是让多个滚动项节奏一致、响应交互、适配不同屏幕宽度,还有内容安全——这些细节往往在第一次上线后才暴露。



















