应使用独立 fixed 定位的全屏 div 作为背景层并设 background-attachment: fixed,文字置于普通定位容器中;需处理 safari 兼容性、文字可读性及移动端 100vh 动态问题。

背景图固定不动但文字滚动,关键在 background-attachment
要让背景图“钉死”在视口里不随滚动移动,而文字照常滚动,核心是给容器设 background-attachment: fixed。但注意:这个属性只对设置了高度(或能撑开高度)且有明确定位上下文的元素生效;直接写在 上看似简单,实际在 Safari 和部分移动端浏览器中会失效或表现异常。
- 推荐做法是用一个全屏
<div> 作为背景层,设 <code>position: fixed; top: 0; left: 0; width: 100%; height: 100vh;,再配background-attachment: fixed - 文字内容必须放在另一个独立的、非 fixed 定位的容器里(比如
<main></main>或普通<div>),否则会被背景层遮盖或一同“锁住” <li>若背景图尺寸不合适,记得同时设 <code>background-size: cover和background-position: center,不然可能裁切或拉伸失真 - 临时缓解方案:给背景容器加
transform: translateZ(0)或will-change: transform,强制启用 GPU 渲染(但可能增加内存占用) - 更稳妥的替代方案:不用
fixed,改用position: fixed+z-index分层——把背景图做成一个独立的<img>或伪元素,用object-fit: cover或background-size控制显示,文字层用position: relative叠在上面 - 不要依赖
的 background —— 多数现代框架(如 React/Vue)会动态操作 body 样式,容易覆盖或冲突 - 最简方案:给文字容器加半透明遮罩层,比如用
::before伪元素 +background: rgba(0,0,0,0.3)覆盖在文字下方(注意 z-index 层级) - 避免纯白/纯黑文字直接压在复杂背景上;可用 CSS
text-shadow做描边(如text-shadow: 0 1px 3px rgba(0,0,0,0.6)) - 如果背景图本身明暗不均,考虑用 SVG 滤镜或
mix-blend-mode: difference动态调整文字颜色——但这在 IE 和旧 Edge 中不支持,慎用 - 安全写法:用
min-height: 100dvh(dvh= dynamic viewport height),目前 Chrome 100+、Safari 16.4+、Firefox 112+ 支持;不支持时回退到100vh - 更通用的 fallback:用 JavaScript 监听
resize,动态设置容器高度为window.innerHeight,但要注意防抖,避免频繁重排 - 测试时务必真机操作——模拟器常忽略地址栏行为,看不出问题
文字滚动时背景不抖动,绕过 Safari 的 background-attachment: fixed bug
Safari 对 background-attachment: fixed 的实现有兼容性问题:滚动时背景会轻微跳动或闪烁,尤其在启用了硬件加速的页面上。这不是代码写错,而是浏览器渲染机制导致的。
文字内容需可读,别被背景图吃掉对比度
背景图再酷,文字看不清就白搭。固定背景 + 滚动文字容易让某些段落恰好滑到图片暗部或纹理密集区,瞬间不可读。
移动端适配时,height: 100vh 不等于屏幕可视高度
在 iOS Safari 和部分安卓浏览器中,地址栏收放会导致 100vh 值动态变化,固定背景层可能突然被截断或留白。这不是 bug,是浏览器把地址栏高度也算进 viewport 了。
真正麻烦的不是怎么写那几行 CSS,而是不同设备对“固定背景”的理解根本不一致;修完 Chrome 再去调 Safari,调完 Safari 发现微信内置浏览器又换一套规则——得一层层试,不能只信文档。











