直接用translateX(-100%)会露白,因-100%指元素自身宽度而非容器宽度,当文本长度不整除容器宽时末尾留空;真正无缝需内容重复、位移精准(如-50%)、动画时长匹配总宽与速度。

为什么直接用 translateX(-100%) 会露白?
常见错误是只复制一次内容、设 @keyframes 从 0% 到 100% 移动 -100%,结果动画一循环就卡顿——因为元素宽度 ≠ 容器可视区宽度,-100% 实际是“自身宽度”,不是“容器宽度”。当文本长度不整除容器宽时,末尾必然留空。
真正无缝的关键不是“动多远”,而是让动画结束帧和起始帧视觉对齐。这就需要内容足够长、位移距离精准、且动画节奏能自然衔接。
- 内容必须至少重复一次(推荐两次),确保滚动过程中始终有后续内容顶上
-
translateX()的终点不能写死-100%,而应设为-50%或计算出的精确负值 - 动画时长需与内容总宽度、滚动速度匹配,否则快慢失衡也会暴露断点
@keyframes 用 translateX(-50%) 怎么不滚一半就停?
设 translateX(-50%) 是为了配合双份内容实现视觉无缝:两段相同文本并排,动画从 0% 滚到 -50% 时,第二段刚好完全进入视口,第一段刚好完全移出;此时立刻循环,等效于“无缝接续”。
这个技巧依赖两个前提:容器 white-space: nowrap + 内容用 inline-block 或 flex 横向排列,且无换行干扰。
立即学习“前端免费学习笔记(深入)”;
- 必须用
display: inline-block或display: flex让文本块整体参与位移,不能是纯block -
padding-left: 100%不再需要,改用transform: translateX(0)起始即可 - 动画时长建议按内容总宽 / 期望速度反推,例如总宽 2000px、想保持 40px/s,则设
animation-duration: 50s
如何用负延迟 animation-delay 消除首帧跳变?
即使用了双内容 + -50% 位移,首次播放仍可能闪一下——因为动画默认从 0% 开始,而内容初始位置未必对齐视觉起点。加负延迟可让动画“提前启动”,把第一帧卡在理想位置。
比如动画总时长是 30s,你想让它从第 10s 的状态开始显示,就设 animation-delay: -10s。浏览器会直接跳转到该时间点对应的关键帧,视觉上就是“自然滚动中”的状态。
- 负延迟值不能超过动画时长,否则行为未定义(多数浏览器会取模或回退)
- 搭配
animation-fill-mode: backwards可确保延迟期间样式不丢失 - 动态内容场景下,需 JS 重新计算总宽后重设
animation-duration和animation-delay
响应式下怎么避免小屏卡顿或错位?
移动端屏幕窄,同样内容在小容器里滚动更快,但若还沿用 PC 端的 animation-duration,就会导致文字“嗖”一下闪过去,甚至因渲染精度问题出现抖动。
更稳妥的做法是用视口单位控制速度,而非固定秒数。例如用 calc(100vw * 15) 当作总位移参考,再结合 animation-timing-function: linear 保证匀速。
- 避免用像素值写死
@keyframes位移,坚持用百分比或vw/vh - 小屏可降级:媒体查询中设
animation: none,改用 JS 滚动或静态展示 -
will-change: transform必须加,否则 iOS Safari 容易掉帧
最易被忽略的是内容更新后的重同步:DOM 改变后,CSS 动画不会自动重算位移逻辑,得手动触发动画重置(比如 toggle class 或修改 animation-name)。否则新加的文本可能卡在中间,破坏无缝感。


















