视差滚动必须用 transform 实现,避免使用 top/margin;所有视差元素需加 will-change: transform;iOS Safari 不支持 background-attachment: fixed,须用 JS 方案;滚动监听需结合 requestAnimationFrame 和 IntersectionObserver 优化性能。

视差滚动必须用 transform,别碰 top/margin
直接改 top 或 margin-top 会导致浏览器频繁触发 layout(回流),滚动一卡一顿。哪怕只动一个背景图,只要用了这些属性,在中低端安卓机或 iOS Safari 上基本就卡成幻灯片。
-
transform: translateY()走 GPU 合成层,不触发布局计算,是唯一靠谱的位移方式 - 所有要视差的元素必须提前加
will-change: transform,否则首帧可能闪一下 - 如果元素是动态插入的(比如 Ajax 加载后 append),记得 JS 插入后立刻执行
el.style.willChange = 'transform'
移动端 iOS Safari 不认 background-attachment: fixed
这个 CSS 属性在 iOS 上基本被无视,加了 -webkit-transform: translateZ(0) 也救不回来。别浪费时间调试它——真要兼容,就得切到 JS 方案。
- 用
getBoundingClientRect().top算元素离视口顶部距离,比单纯依赖window.scrollY更稳,能适配嵌套滚动容器 - 滚动监听必须包一层
requestAnimationFrame,否则快速滑动时掉帧明显 - 避免在同一个滚动区域里混用
position: sticky,iOS 下会定位错乱甚至抖动
HTML 结构要分层清晰,别全塞在一个 section 里
视差不是靠一堆 div 堆出来的,而是靠 DOM 层级 + CSS z-index + JS 控制速度协同生效。结构乱了,后期调速、叠加、响应式都会出问题。
- 每个视差区块用
<section class="parallax-layer" data-speed="0.3">包裹,data-speed控制移动比例 - 背景层放最底层(
z-index: 1),内容层放上层(z-index: 2),确保文字不被遮挡 - 不要把所有背景图都设成
background-image,需要独立控制速度的,直接用<img>或<div>元素更灵活
性能陷阱:没进视口就别算偏移量
页面拉到底部才出现的视差区块,如果一加载就绑定 scroll 监听并计算 getBoundingClientRect(),等于白跑几十次无效计算。尤其当页面很长、视差元素很多时,CPU 负载直接拉高。
立即学习“前端免费学习笔记(深入)”;
- 用
IntersectionObserver判断元素是否进入视口,进了再启动视差逻辑 - 滚动事件里别直接操作 DOM 样式,先存偏移值,再由
requestAnimationFrame统一更新 - 如果某层视差只是装饰性背景,且不需要精确对齐,考虑降级为纯 CSS
background-attachment: fixed(仅限 PC 端)
overflow: hidden 或 transform,getBoundingClientRect() 虽然数值还准,但渲染可能被截断——得手动检查是否显示完整。



















