background-attachment: fixed 仅在 body 上且无 transform/filter/opacity<1/will-change 时生效,需 height: 100vh 等约束;移动端基本失效,应改用 perspective + translateZ 或 scroll 监听 JS 方案。

background-attachment: fixed 在绝大多数实际页面中根本不会生效——不是你漏写了 background-image,也不是没设 height,而是浏览器主动把它当摆设了。
为什么 background-attachment: fixed 总是“没反应”
它只在极窄条件下能跑通:必须直接写在 body 上,且 body 不能有任何触发层叠上下文的样式。一旦加了 transform、filter、opacity: 0.99 或 will-change,Chrome v99+ 和所有 Safari 就静默降级为 scroll,控制台连 warning 都不抛。
-
background-attachment只对设置了background-image的元素起效;纯色或渐变背景也得显式声明图片(哪怕用url("data:image/svg+xml,")占位) - 移动端 iOS Safari 几乎完全无视该属性,哪怕写在
body上也大概率退化 - 如果容器靠内容撑高(比如没设
height或min-height),视差行为会直接消失
真正能跑通的最小可行写法
绕过兼容性陷阱的最简路径,是放弃“多层视差”,只做单层固定背景,并严格约束容器层级和样式组合。
- 把背景直接加在
body上,且确保body { height: 100vh; margin: 0; overflow-x: hidden; } - 必须配套这四句:
background-size: cover、background-position: center、background-repeat: no-repeat、background-attachment: fixed - 禁止在
body或其任意父级(html)上使用transform、filter、opacity < 1、will-change - 移动端要加降级:
@supports not (background-attachment: fixed) { ... }里换回scroll+background-size: 100% auto防拉伸
想做多层视差?别硬刚 fixed,换方案
真需要前景/中景/背景不同速滚动,background-attachment: fixed 已不适合——它只支持“固定 or 滚动”,没有中间速度。强行套多个 fixed 层只会全部卡死在视口,失去纵深感。
立即学习“前端免费学习笔记(深入)”;
- 用
transform: translateZ()+perspective是目前最可控的替代:给外层容器设perspective: 1px,各层分别设translateZ(-0.5px)、translateZ(-1px)等负值,越负越“远”,再配scale()补偿缩放 - JS 方案更灵活:监听
scroll事件,用requestAnimationFrame动态改各层background-position的y值,按比例偏移;但注意别在回调里直接改style.top,要用transform: translateY() - 移动端必须做的降级处理:别指望
fixed在手机上工作。真要上线,必须用@supports not (background-attachment: fixed)做兜底,或者直接按 UA 判断 iOS/Android
最常被忽略的点是:你以为在子容器上写 background-attachment: fixed 是在做视差,其实只是在写一段注定被浏览器跳过的 CSS。真正起效的永远只有那一小段受控于根滚动容器、无干扰样式的 body 背景——其余都得靠 perspective 或 JS 才能落地。


















