background-attachment: fixed 仅在严格条件下生效:必须设于 body 上且无层叠上下文样式,需配合 height: 100vh 等四属性,并禁用 transform/filter/opacity<1/will-change;移动端应降级为 scroll;多层视差推荐 translateZ + perspective 或 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)等负值,越负越“远”,滚动时移动越慢 - 必须配套
transform-style: preserve-3d,否则子元素会被拍平 - 要补偿因 Z 轴缩放导致的尺寸变化,加
scale(2)或类似值手动拉回原大小 - JS 方案更灵活:监听
scroll事件,用requestAnimationFrame动态改各层background-position的 y 值,按比例偏移
真正麻烦的从来不是“怎么写 CSS”,而是判断哪一层该用 pointer-events: none、哪些 translateZ 值在低端 Android 上会触发渲染抖动、以及 scale 补偿公式里那个分母到底该用 perspective 还是 perspective * 2 ——这些细节不试到真机上,光看文档永远踩不准。


















