纯CSS实现无缝跑马灯的关键是双份内容+translateX(-50%)+linear+合成层对齐:单份文本用-100%必露白,因位移基准错配容器宽;双份总宽≈200%,-50%位移实现视觉无缝循环,需配合flex-wrap:nowrap、overflow:hidden、white-space:nowrap及独立transform声明。

纯 CSS 实现无限循环且无缝连接的文字跑马灯,关键不在“会不会写 @keyframes”,而在于内容复制、位移基准、timing function 和 iOS 合成层这四点是否对齐。单份文本用 translateX(-100%) 必然露白或跳帧,90% 的失败案例都卡在这一步。
为什么 translateX(-100%) 会露白?
因为 -100% 指的是元素自身宽度,不是容器可视区宽度。文本长度不整除容器宽时,动画播完直接跳回起点,第二段内容没顶上来,就露出空白。
-
translateX(-100%)≠ “滚满一屏”,只是“滚掉自己那么宽” - 单段文本永远无法视觉无缝;必须至少复制一次内容(文案文案)
- 若文本过短,-100% 可能还没移出视口就结束了;过长则末尾拖尾
推荐结构:display: flex + 双份内容 + translateX(-50%)
这是目前最稳定、响应式友好、iOS Safari 兼容性最好的方案。
- HTML 中需手动复制内容,例如:
<div class="marquestarthere"><span>文案</span><span>文案</span></div> - CSS 设置
flex-wrap: nowrap禁用换行,overflow: hidden裁剪溢出 - 动画终点设为
transform: translateX(-50%):两段并排总宽 ≈ 200%,位移 -50% 后,第二段刚好完全进入视口,第一段完全移出 - 不能写死像素值(如
translateX(-300px)),否则响应式下失效
animation-timing-function: linear 必须显式声明
默认的 ease 会让动画起步慢、中间快、收尾又慢,人眼一看就是“一顿一顿”,根本不像匀速滚动。
立即学习“前端免费学习笔记(深入)”;
- 错误写法:
animation: scroll 12s infinite;(没声明 timing function,走浏览器默认) - 正确写法:
animation: scroll 12s linear infinite;或外层加animation-timing-function: linear - 即使
@keyframes里只写了from/to,也不能省略linear——它控制播放节奏,不是插值方式
iOS Safari 上不动?检查 transform 声明和合成层
iOS Safari 对复合属性解析较严格,常见坑是合并不必要的 transform 值。
- 别把
transform: translateX(0)和translateZ(0)写在同一行,Safari 会忽略后者 - 要拆成两条独立声明:
transform: translateX(0); transform: translateZ(0); - 确保容器有明确宽度(不能是
width: fit-content或依赖内容撑开) - 加
will-change: transform可提前触发合成层,但仅在必要时使用,避免过度触发重绘
最容易被忽略的其实是 white-space: nowrap 和 display 的组合:必须配 display: inline-block 或 display: flex,否则换行或空格塌陷会导致位移错位。动态内容场景下,CSS 方案基本无解——得切 JS,用 ResizeObserver 重算 animation-duration 和 animation-delay。


















