纯css无缝滚动必须复制内容并精确位移,单份内容用translatex(-100%)会因内容不足导致露白;横向推荐flex+双份内容+translatex(-50%),纵向需固定行高与容器高度对齐,hover暂停用animation-play-state最可靠。

纯 CSS 实现无缝滚动完全可行,但必须复制内容 + 精确控制位移距离,否则必然出现跳帧、空白或卡顿。
为什么单份内容加 translateX(-100%) 会露白
浏览器渲染时,transform: translateX(-100%) 是把元素整体向左推「自身宽度」,但容器只显示第一份内容的可视区域;当它移出后,后面没内容接上,就会露出父容器背景色(即“露白”)。这不是动画问题,是 DOM 内容不足导致的视觉断层。
- 常见错误现象:
scroll-content滚到一半突然变空、文字/图片消失一帧、结尾有明显停顿 - 根本原因:动画终点值未对齐真实内容总宽,或未提供冗余内容
- 正确做法:必须准备至少两轮相同内容(DOM 复制),再用动画让它们“接力”滚动
横向滚动推荐方案:flex + 双份内容 + translateX(-50%)
这是目前最稳定、兼容性好、无 JS 依赖的横向无缝滚动写法。关键不在“-100%”,而在“-50%”——因为内容已翻倍,总宽是原始的 200%,所以位移一半就刚好回到逻辑起点。
- HTML 中需手动或脚本复制一次内容:
<div class="scroll-list"> <span>A</span><span>B</span><span>C</span><span>A</span><span>B</span><span>C</span> </div>
- CSS 设置:
display: flex + <code>width: max-content(避免 flex 自动换行) - @keyframes 动画终点必须是
transform: translateX(-50%),不能写-100%或像素值 - 性能提示:加
will-change: transform可触发硬件加速,尤其在低端设备上更顺滑
纵向滚动要注意行高与容器高度对齐
垂直无缝滚动比横向更容易出错,因为 line-height、padding、字体渲染微差都会让 translateY(-100%) 错位一两个像素,造成滚动抖动或卡顿。
- 必须固定容器高度(如
height: 60px)和单行内容高度(如line-height: 60px) - 内容区域总高度应为单行高度 × 行数 × 2(双份),动画终点设为
translateY(-50%)更稳妥 - 避免使用
em或rem控制行高,优先用px保证像素级一致 - 若内容含图片,记得设
vertical-align: top,否则默认 baseline 对齐会产生意外间隙
鼠标悬停暂停必须用 animation-play-state
很多教程用 pointer-events: none 或 JS 控制暂停,反而破坏语义和可访问性。原生 CSS 方案最轻量也最可靠。
- 只需一行:
.scroll-container:hover { animation-play-state: paused; } - 注意选择器要精确匹配动画所在元素,不是父容器就是子容器,别套错层级
- 如果用了多个动画(比如文字+图标不同速),需分别加 hover 控制,或统一用一个 animation-name
- 移动端不触发
:hover,如需触摸暂停,得额外加 JS 监听touchstart切换 class
最容易被忽略的是内容宽度计算——哪怕只差 0.5px,动画循环点就会偏移,人眼虽难察觉,但连续滚动几十秒后,错位会累积成明显卡顿。建议所有尺寸用整数 px,禁用百分比宽度和自动 margin。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











