animation: infinite 不能直接实现无缝滚动,因默认 from-to 线性过渡导致末尾跳回;需双文本拼接+translatex(-100%)百分比位移+white-space: nowrap+overflow: hidden+will-change: transform 消除跳跃与卡顿。

为什么 animation: infinite 不能直接让文字无缝滚动?
很多人一上来就写 animation: marquee 10s linear infinite,结果发现文字滚到末尾会“咔”一下跳回开头,根本不是流畅跑马灯。问题不在循环次数,而在动画关键帧没处理好位移衔接——CSS 动画默认用 from 到 to 线性过渡,但文字容器宽度固定,内容长度又远大于容器,必须靠精确的 transform: translateX() 偏移+重复内容来制造视觉连续性。
如何用双份文本 + 百分比位移实现真正无缝
核心思路是:把文字复制两份拼在一起,让动画从 0% 位移到 -100%,刚好让第二份文字完全接上第一份的结尾。这样浏览器渲染时不会重绘跳跃。
- 容器设
white-space: nowrap防止换行,overflow: hidden隐藏溢出 - 子元素(文字)设
display: inline-block,并用animation-timing-function: linear保证匀速 - 关键帧中,
0%对应translateX(0),100%对应translateX(-100%),注意这里百分比是相对于自身宽度,不是父容器 - 示例结构:
<div class="marquee"><span>Hello World Hello World </span></div>
@keyframes 里用 100% 还是 to?有区别吗?
没本质区别,但用 100% 更稳妥。某些旧版 Safari 对 to 解析偶发异常,尤其配合 calc() 或动态宽度时。更关键的是:如果你后续想用 JS 控制动画进度(比如暂停/加速),用百分比数值更方便做插值计算。
- 别写
to { transform: translateX(-200px); }—— 绝对像素值无法适配不同字号或缩放 - 务必写
100% { transform: translateX(-100%); },这里的-100%指子元素自身宽度 - 如果文字含空格或
,确保它们也被包含在子元素内,否则位移基准错乱
移动端卡顿、闪烁或突然跳帧怎么办?
跑马灯在 iOS Safari 或低端 Android 上容易掉帧,主因是 translateX() 触发了重排而非纯合成。加一行 will-change: transform 能提示浏览器提前升层,但别滥用——只加在实际动的元素上(即 span),而不是父容器。
- 避免在动画中同时修改
color或font-size,这些属性会强制重绘 - 若文字很长,建议限制最大宽度,用
max-width: 500px配合font-size: clamp()防止超宽容器撑爆布局 - 测试时用 Chrome DevTools 的 “Rendering” 面板勾选 “Paint flashing”,确认只有滚动区域在刷新
inline-block 默认有基线对齐带来的微小间隙,可能造成位移不精准。加 font-size: 0 在父容器,再在子元素里重设字体大小,能彻底消除这个误差。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











