ios safari 中 background-attachment: fixed 失效是因性能限制被主动忽略,需用 requestanimationframe + transform 实现跨端稳定视差,注意 touchmove 需 preventdefault 且设 passive: false,推荐 intersectionobserver 懒加载局部视差。

纯 CSS 的 background-attachment: fixed 在 iOS Safari 上基本失效,别把它当主力方案;真要稳定跨端,得用 JavaScript 驱动 transform: translateY() + requestAnimationFrame 节流。
background-attachment: fixed 为什么在手机上不动
这不是 bug,是 Safari(尤其是 iOS ≤ 15)和部分安卓 WebView 的明确限制:出于性能考虑,直接忽略该声明。你检查 computed styles 会看到 background-attachment 被标为 invalid 或直接消失。
- 必须加
-webkit-background-attachment: fixed才可能生效,但真机测试仍常失败 - 父容器若有
transform、will-change、overflow: hidden,fixed 会被强制降级 - 元素高度不能是
height: auto,得写死100vh或具体像素值 - 图片尺寸建议 ≥ 1920×1080px,否则缩放后模糊,反而暴露缺陷
用 scroll + requestAnimationFrame 做可控视差
核心不是“怎么算”,而是“怎么不卡”。直接在 scroll 事件里改 style.transform 会导致每帧重绘,低端机明显掉帧。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 把滚动位置缓存成变量(如
let lastScrollY = window.scrollY),只在requestAnimationFrame回调里读取并更新偏移 - 偏移量用
window.scrollY * 0.3这类系数控制速度,“0.3”越小越像远处背景,“0.8”越近越快 - 所有参与视差的元素必须设
position: relative或absolute,否则transform可能不生效 - 加
will-change: transform或transform: translateZ(0)提前升层,防首帧闪烁
移动端 touchmove 必须 preventDefault
iOS Safari 默认禁用 window.scrollY 在 touchmove 中的更新,导致视差完全不动——这不是 JS 写错了,是平台行为。
- 监听
touchmove时,必须调用event.preventDefault(),否则scrollY值冻结在初始状态 - 但加了
preventDefault()后,页面本身无法滚动,所以得用{ passive: false }显式声明 - 更稳妥做法:只在用户真正开始拖拽时启用视差逻辑,避免全局监听干扰原生滚动
- 真机测试不可省:Chrome DevTools 的模拟器无法复现 Safari 的
touchmove行为
IntersectionObserver 适合局部懒加载视差
如果你的视差只在某个区块进入视口时才需要(比如“技能条”随滚动浮现),没必要监听全局 scroll——资源浪费且易冲突。
- 用
IntersectionObserver监听目标元素的intersectionRatio,值从 0 到 1,天然表示可见比例 - 在回调里算位移:
element.style.transform = `translateY(${(1 - entry.intersectionRatio) * 80}px)` - 初始化传
{ threshold: [0, 0.25, 0.5, 0.75, 1] },可分阶段响应,比单纯 onEnter 更细腻 - 它不依赖
scrollY,不受touchmove限制,iOS 兼容性远好于 scroll 方案
最易被忽略的点:视差元素如果动态插入(比如 Ajax 加载后 append),will-change: transform 得 JS 插入后立刻补上,否则第一帧必闪;另外,别在同一个容器里混用 position: sticky 和视差逻辑,WebKit 会直接放弃合成层调度。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










