最可靠方案是用伪元素模拟:body::before { position: fixed; background-image: url('bg.jpg'); z-index: -1; pointer-events: none; },因background-attachment: fixed在Safari iOS等环境不支持且性能差。
背景图片固定不动,核心是用 background-attachment: fixed,但它在现代浏览器(尤其是移动端和 Safari)中存在兼容性与性能问题,不能无脑套用。
这是最直接的实现方式,让背景图随视口滚动而“静止”,产生视差效果:
body {
background-image: url('bg.jpg');
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
background-attachment: fixed;
}
注意:background-attachment: fixed 只对 body 或设置了 overflow: hidden 的容器生效时才稳定;在普通滚动容器里可能被忽略。
background-position 和 background-size 才能保证居中与缩放合理transform(如 translateZ(0))、perspective 或 will-change,某些 Chrome 版本会强制禁用 fixed
background-attachment: fixed(包括 body 和任何元素)当 background-attachment: fixed 在 iOS 或安卓 WebView 中彻底失效时,主流解法是用 ::before 伪元素 + position: fixed:
body {
margin: 0;
}
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('bg.jpg');
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
z-index: -1;
pointer-events: none;
}
关键点:
z-index: -1 确保内容层在图片之上pointer-events: none 防止伪元素拦截点击事件
body 清除默认 margin,否则 fixed 元素可能错位
background-attachment: local 或监听 scroll 动态修正位置(较重)background-attachment: local 表示背景图随元素内容滚动而滚动——这和“固定不动”完全相反,容易混淆:
scroll:背景图随容器滚动(默认值)fixed:背景图相对于视口固定(目标效果,但兼容差)local:背景图随容器内可滚动内容一起动(比如 div 内部有 overflow,背景会跟着文字滚)所以想“不动”,就别选 local;它只在极少数需要背景随局部内容滑动的场景才有用,比如带滚动条的卡片背景。
用 fixed 或伪元素做背景图,都可能触发频繁重绘,尤其在低端 Android 设备上卡顿明显:
background-blend-mode 或多层 fixed 背景叠加@media (prefers-color-scheme: dark) 微调亮度或替换图真正稳定的“固定背景”,现在基本等于“用伪元素 + fixed 定位 + 严格控制尺寸和交互”,background-attachment: fixed 更像是一个渐进增强的彩蛋,而不是可靠方案。