用 transform: translatex() 实现多层云视差需按近快远慢设不同动画时长与位移值,位移≥100%防断帧;必加 will-change: transform 和 backface-visibility: hidden 启用合成层;禁用 background-position 方案;滚动时通过 touch 事件暂停动画防卡顿。

用 transform: translateX() 实现多层云速差
视差感本质是让不同层的云以不同速度水平移动,近处快、远处慢。CSS 里最稳的方式是用 transform: translateX() 配合 @keyframes,别用 left 或 margin-left —— 它们会触发重排,动画卡顿明显。
关键在「时间 + 距离」的组合:同一段动画时长下,位移值越大,视觉速度越快。比如:
- 近层云:
animation: moveCloud 40s linear infinite+transform: translateX(-200%) - 中层云:
animation: moveCloud 65s linear infinite+transform: translateX(-150%) - 远层云:
animation: moveCloud 120s linear infinite+transform: translateX(-100%)
注意位移百分比要 ≥100%,否则动画会“断帧”——云跑到一半就跳回起点,肉眼可见卡顿。
为什么必须用 will-change: transform 和 backface-visibility: hidden
不加这两句,尤其在 Safari 或低端 Android 上,云层容易闪烁、掉帧,甚至出现半透明撕裂。这不是玄学,是浏览器对合成层(compositing layer)的调度策略问题。
will-change: transform 是明确告诉浏览器:“这玩意儿要动了,提前准备 GPU 图层”;backface-visibility: hidden 则强制启用硬件加速,同时避免某些安卓 WebView 的渲染 bug。
- 只加在动画元素本身上,别滥用到父容器
- 如果云是
background-image,得包一层<div> 才能加这些属性 <li>Chrome DevTools 的 “Layers” 面板可验证是否真启用了合成层(搜 <code>transform层) - 当容器宽高比变化(比如响应式横屏/竖屏切换),
background-position的百分比基准会变,云层突然“跳速”或错位 - 如果云图用了
background-size: cover,动画过程中图像会被反复重采样,边缘模糊、细节糊成一片 - 无法单独控制某一层的缩放或 opacity,所有云绑定在同一张背景图上,灵活性归零
- 用
@media (prefers-reduced-motion: reduce)是基础,但不够 - 更可靠的是监听
touchstart和touchend,给 body 加临时 class,比如is-scrolling,然后 CSS 写:.is-scrolling .cloud-layer { animation-play-state: paused; } - 别用
pointer-events: none或visibility: hidden,会影响布局和后续交互
background-position 方案的坑:循环错位与缩放失配
有人图省事用 background-position 动画推云图,但实际线上很容易翻车:
真要用背景图方案,至少把每层云拆成独立 <div>,各设自己的 <code>background-image 和 background-size,再统一用 transform 动。
移动端 touch 滚动时如何禁用动画(防卡死)
iOS Safari 和部分安卓浏览器在滚动中强行渲染 CSS 动画,会导致严重掉帧,用户一滑屏幕,云就“定格”或“抽搐”。不能靠 JS 监听 scroll——太晚,帧已经丢了。
动画暂停不是终点,而是过渡——松手后 150ms 内恢复,否则用户会觉得“云反应迟钝”。这个延迟得自己测,不同设备差异挺大。











