background-attachment: fixed 在移动端被浏览器静默降级为 scroll,因重绘压力大;可靠视差需改用 background-position + scroll 事件或 CSS scroll-driven animations 实现线性位移。

background-attachment: fixed 在绝大多数现代移动浏览器中根本不会生效——不是你写错了,是 Chrome(v56+)、Safari(更早)和主流安卓 WebView 主动禁用它。真要实现可靠视差,得换思路。
为什么 background-attachment: fixed 在移动端显示为 scroll
浏览器不是“不支持”,而是静默降级:滚动时 fixed 背景需频繁重绘合成层,对移动 GPU 和内存压力大,所以直接 fallback 到 scroll。你在 CSS 里写了 background-attachment: fixed,但在 DevTools 的 Computed 面板里看到的值却是 scroll,这就是典型表现。
以下情况会加剧失效概率:
- 父容器用了
transform(如translateZ(0))、filter(如blur(1px))或will-change - 背景图设在非根滚动容器上(比如嵌套在
.wrapper > .section里,而非body或全屏.hero) - 页面启用了
overflow: hidden或存在多层滚动上下文
用 background-position + scroll 事件模拟视差(兼容性最好)
核心是放弃“固定”,改走“主动位移”:监听滚动距离,动态算出背景偏移量,再更新 background-position。比 fixed 更可控,也规避了移动端硬伤。
立即学习“前端免费学习笔记(深入)”;
- 必须显式声明
background-attachment: scroll,避免继承干扰 - 用
requestAnimationFrame节流scroll事件,别直接绑在window.addEventListener('scroll', ...)上 - 位移比例建议控制在
0.2~0.6之间,例如:element.style.backgroundPosition = 'center ' + (window.scrollY * 0.4) + 'px' - 背景图尺寸至少是容器宽高的 2 倍,否则位移时边缘露白;搭配
background-size: cover和background-repeat: no-repeat
用 CSS scroll-driven animations 实现原生平滑视差(Chrome 115+ / Safari 17.4+)
这是目前唯一真正“滚动即动画”的方案:位移与滚动距离严格线性映射,快滚慢滚体验一致,且不依赖 JS。
- 基础写法需三部分:@keyframes 定义
background-position变化、@scroll-timeline规则声明滚动轴、元素上用animation-timeline: scroll(--parallax) - 必须加
contain: layout style paint到滚动容器,否则动画可能卡顿或跳帧 - 检查支持性用
CSS.supports('animation-timeline', 'scroll()'),不支持时 fallback 到 JS 方案 - 注意:
animation-timeline: scroll(root)绑定全局滚动;若想绑定局部区域,得写scroll(.container),且该容器需有明确滚动上下文(如overflow-y: auto)
容易被忽略的关键点
所谓“平滑”,不是指动画帧率高,而是背景位移必须与滚动距离保持严格线性关系。background-attachment: fixed 天生做不到这点——它本质是冻结背景,和滚动解耦,没有中间帧,也不响应滚速变化。iOS Safari 上还常出现撕裂或闪烁。真要交付生产环境,得从滚动事件源或 scroll-timeline 入手对齐,而不是反复调 fixed 的写法。


















