background-attachment: fixed 在现代浏览器尤其移动端基本不可靠,因Chrome v56+和Safari主动降级为scroll;稳定方案只有window.scrollY+background-position动态计算或@scroll-timeline驱动CSS动画。

background-attachment: fixed 在现代浏览器中基本不可靠,尤其在移动端完全失效——这不是你写错了,是 Chrome v56+ 和 Safari 主动降级为 scroll。真正能跨端稳定工作的方案只有两个:用 window.scrollY + background-position 动态计算,或用 @scroll-timeline 驱动 CSS 动画。
为什么 background-attachment: fixed 大概率不生效
这个属性依赖浏览器将背景绑定到视口坐标系,但现代渲染引擎做了多重限制:
- 父容器只要用了
transform、will-change、filter或opacity(哪怕只是opacity: 0.99),就会触发新层叠上下文,fixed立即退化为scroll - iOS Safari 和多数安卓 WebView 默认禁用,DevTools 里看到的
background-attachment计算值就是scroll - 即使写在
body上,Chrome v99+ 也要求它必须是“根滚动容器”,.parallax-section这类子容器即使样式全对,也可能不生效 -
position: sticky或overflow: hidden的祖先元素也会干扰合成层判定
用 window.scrollY + background-position 模拟(最通用)
监听滚动并手动设置背景偏移,兼容性好、可控性强,且能精确控制速度比:
- 目标元素必须显式声明
background-attachment: scroll,避免继承干扰 - JS 中用
requestAnimationFrame节流,不要直接绑scroll事件,否则卡顿明显 - 位移比例建议控制在
0.2~0.6之间;例如:element.style.backgroundPosition = 'center ' + (window.scrollY * 0.4) + 'px' - 背景图必须设
background-size: cover或明确宽高,否则移动时边缘易露白 - 若页面有多个视差区块,每个需独立计算偏移,不能共用同一
scrollY值直接套用
用 @scroll-timeline + animation-timeline(现代但需兜底)
Chrome 115+、Safari 17.4+ 支持,纯 CSS、性能更好,但关键帧只能驱动 background-position,不能用 transform:
立即学习“前端免费学习笔记(深入)”;
- 基础写法:
animation: parallax 1s linear both; animation-timeline: scroll(root auto); - 必须配合
scroll-timeline-axis: y(默认就是 y 轴),且容器需有明确滚动上下文 - 检查支持性:
CSS.supports('animation-timeline', 'scroll()'),不支持时 fallback 到 JS 方案 - 多层视差需复用同一
scroll-timeline,但各层用animation-range分段控制触发区间,并在@keyframes中显式定义不同位移幅度
真正难的不是写出第一版效果,而是让视差在各种设备、各种嵌套结构、各种 CSS 上下文中都保持一致——z-index 错乱、will-change 干扰、父容器 overflow 截断,这些才是上线前最常卡住的地方。


















