水平滚动须用@keyframes+transform:translateX()避重排,设overflow:hidden时子元素宽度要足够;垂直滚动防文字模糊需对齐像素或加backface-visibility:hidden;动画必须用linear;iOS卡顿应改用requestAnimationFrame或加translateZ(0)。

用 @keyframes + transform: translateX() 实现水平自动滚动
直接改 left 或 margin-left 会触发重排,性能差;必须用 transform 才能走 GPU 加速。关键帧里只写起始和结束的 translateX() 值,浏览器会自动补间。
常见错误是把容器设为 overflow: hidden 但子元素没设足够宽度,导致滚动内容被截断。要确保滚动区域(比如 .scroll-track)的 width 大于其父容器,且内部元素用 display: inline-block 或 flex 排成一行。
- 动画时长建议设为
20s以上,太快人眼跟不上,太慢又像卡住 - 用
infinite循环,但注意首尾衔接:最后一帧的位移值应等于第一帧的负值(比如从0到-100%),否则会跳变 - 如果滚动内容是图片或卡片,建议加
will-change: transform提前提示浏览器优化
垂直滚动动画怎么避免文字模糊
用 translateY() 做垂直滚动时,若出现文字发虚、锯齿,大概率是元素落在非整像素位置。CSS 动画默认使用小数位移,而文本渲染对 subpixel 敏感。
解决办法不是关掉平滑,而是让位移始终对齐像素:在关键帧中用 calc() 或固定像素值,比如 translateY(-200px) 而非 translateY(-50%);或者给滚动容器加 backface-visibility: hidden 强制硬件加速并改善渲染质量。
- 慎用百分比位移做垂直滚动,尤其当容器高度不固定时,
50%可能算出小数 - 如果必须用百分比,可在父容器上设
font-size: 0消除 inline 元素间的空白间隙,再用line-height: 1防止行高干扰计算 - 测试时打开 Chrome DevTools → Rendering → “Paint flashing”,看滚动区域是否频繁重绘
animation-timing-function 选 linear 还是 ease
自动滚动要求速度恒定,人眼才觉得是“匀速带”;用 ease 或 cubic-bezier(.4,0,.6,1) 会导致启停顿挫,破坏连续感。所有滚动动画都应强制设为 linear。
例外情况只有做“模拟传送带启动/刹车”效果时才考虑缓动,但那是设计需求,不是功能需求。绝大多数业务场景(如新闻跑马灯、产品轮播条)必须用 linear。
- 别依赖浏览器默认 timing-function,显式声明
animation-timing-function: linear - 如果用了
steps(),那是逐帧跳跃,不是滚动,别混淆 - 配合
animation-play-state: paused做 hover 暂停时,linear也能保证恢复后无缝接续
移动端 Safari 上动画卡顿或闪退怎么办
iOS Safari 对长时间运行的 @keyframes 动画有资源回收机制,尤其当页面切到后台再切回,动画可能中断或错位。这不是 bug,是系统限制。
根本解法是不用纯 CSS 实现长周期滚动,改用 requestAnimationFrame + transform 的 JS 方案,可控性更强。但如果坚持用 CSS,至少加两道保险:
- 动画时长不要超过
60s,iOS 对超长动画更敏感 - 给动画元素加
-webkit-transform: translateZ(0)强制开启硬件加速(仅 Safari 有效) - 监听
visibilitychange事件,在页面不可见时暂停动画,可见时重置animation-play-state和animation-delay
最麻烦的点其实是“无缝循环”——CSS 动画没法动态计算内容总宽,JS 方案可以实时读取 scrollWidth 并重设位移终点,这点纯 CSS 做不到。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











