最简方案是直接给 body 加 background-attachment: fixed,但 iOS Safari 和部分安卓 WebView 不支持,且 Chrome 在 body 有 transform 等属性时也会禁用;推荐用 body::before 伪元素模拟 fixed 效果,需设 position: fixed、z-index: -1、pointer-events: none,并确保 background-size: cover 和 background-position: center。

直接给 body 加 background-attachment: fixed 是最简方案,但 iOS Safari 和部分安卓 WebView 会无视它——别信“写了就完事”。
为什么 background-attachment: fixed 在移动端常失效
这个属性本意是让背景图绑定到视口(viewport),滚动时图像位置不变。但它在 Safari for iOS 上从不支持,在某些安卓 WebView 中也会被降级为 scroll。更麻烦的是:body 上若存在 transform、perspective 或 will-change,Chrome 某些版本会直接禁用该行为。
- 不是你代码写错了,是浏览器主动不执行
-
background-attachment: local完全反向——它会让背景随容器内滚动内容一起动,千万别混用 - 即使桌面端生效,iOS 用户打开页面后背景照常滚动,体验断裂
用 ::before 伪元素模拟 fixed 效果(推荐)
这是目前兼容性最强、性能可控的落地方式:把背景图从 body 背景剥离,用固定定位的伪元素承载。
关键 CSS:
立即学习“前端免费学习笔记(深入)”;
body {
margin: 0;
}
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('bg.jpg');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
z-index: -1;
pointer-events: none;
}
-
margin: 0必须加,否则fixed元素会因默认 body 边距错位 -
z-index: -1确保内容层(文字、按钮等)自然盖在背景上 -
pointer-events: none防止伪元素拦截所有点击事件——这点极易漏掉 - 如果页面有横向滚动(比如超宽表格),需额外监听
scroll动态修正left值,但多数场景不需要
background-size 和 background-position 不只是“好看”,而是功能前提
没配好这两个,fixed 或伪元素都会白搭。例如 background-size: 100% 100% 会拉伸变形;background-position: top left 在不同屏幕下可能只露出图片一角。
- 优先用
cover:等比缩放并填满,适合大图,但可能裁剪边缘 - 用
contain:完整显示整张图,但会有留白,适合 Logo 类小图 -
background-position: center center是安全起点;若要适配移动端,可配合@media (max-width: 768px)微调偏移量 - 别依赖
height: 100%—— 它要求父容器有明确高度,100vh更可靠,但注意 iOS Safari 的vh计算 bug(地址栏收起/展开时变化),此时伪元素方案反而更稳
真正难的不是写对一行 CSS,而是判断什么时候该放弃原生属性、转而用伪元素接管——尤其当项目必须跑在 iOS 设备上时,这点绕不开。


















