仅用CSS实现多背景视差效果:解决背景重叠问题
解决多背景视差的重叠问题
其实你遇到的这个问题我之前也踩过坑——用position: fixed实现单背景视差没问题,但加第二个就重叠,核心原因是fixed定位是相对于整个浏览器视口的,所有设置了position: fixed的背景元素都会固定在视口的同一个位置,层级又默认相同,自然会叠在一起,而且不会随着内容滚动自动切换显示。
下面给你两种纯CSS的解决方案,都是我实际用过的,效果不错:
方法一:用section容器配合background-attachment: fixed(最常用)
这种方法不需要额外的fixed元素,直接给每个内容区块绑定背景,利用CSS原生的背景属性实现视差,同时天然避免重叠。
代码示例
首先是CSS:
/* 全局重置,去掉默认边距和内边距 */ * { margin: 0; padding: 0; box-sizing: border-box; } /* 视差背景区块:占满整个视口高度 */ .parallax-block { height: 100vh; background-size: cover; /* 让背景铺满容器 */ background-position: center; /* 背景居中显示 */ background-attachment: fixed; /* 核心!让背景相对于视口固定,实现视差 */ } /* 内容区块:用来放文字内容,和背景区块交替出现 */ .content-block { height: 100vh; padding: 3rem; background-color: #fff; font-size: 1.2rem; line-height: 1.8; } /* 给每个视差区块设置不同背景图 */ .block-1 { background-image: url('你的第一张图片路径'); } .block-2 { background-image: url('你的第二张图片路径'); }
然后是HTML结构:
<!-- 第一个视差背景 --> <div class="parallax-block block-1"></div> <!-- 第一个内容区块 --> <div class="content-block"> <h2>这里是第一个内容区</h2> <p>滚动页面就能看到视差效果啦,背景会固定不动,内容滚动~</p> </div> <!-- 第二个视差背景 --> <div class="parallax-block block-2"></div> <!-- 第二个内容区块 --> <div class="content-block"> <h2>这里是第二个内容区</h2> <p>两个背景不会重叠,因为每个视差区块占满视口,滚动到对应位置才会显示它的背景</p> </div>
原理说明
background-attachment: fixed会让背景图固定在视口,而parallax-block本身是随着页面滚动的。当某个parallax-block滚动到视口范围内时,它的背景就会铺满整个视口,因为每个区块都占满100vh,所以不会和其他背景重叠。
方法二:用CSS滚动驱动动画控制fixed背景的显示(进阶)
如果你一定要用position: fixed的元素来实现,可以借助CSS的滚动驱动动画,根据滚动位置切换不同背景的可见性,避免重叠。
代码示例
CSS部分:
/* 全局重置 */ * { margin: 0; padding: 0; box-sizing: border-box; } /* 固定定位的背景元素 */ .parallax-bg { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-size: cover; background-position: center; z-index: -1; opacity: 0; /* 默认隐藏 */ /* 绑定滚动驱动动画 */ animation: toggleVisibility linear; animation-timeline: scroll(root); /* 基于根元素的滚动进度 */ } /* 第一个背景:滚动前50%范围显示 */ .bg-1 { background-image: url('你的第一张图片路径'); animation-range: 0% 50%; } /* 第二个背景:滚动后50%范围显示 */ .bg-2 { background-image: url('你的第二张图片路径'); animation-range: 50% 100%; } /* 动画关键帧:控制透明度 */ @keyframes toggleVisibility { 0%, 100% { opacity: 0; } 10%, 90% { opacity: 1; } } /* 足够长的内容区块,触发滚动 */ .long-content { height: 200vh; padding: 3rem; background-color: rgba(255,255,255,0.8); }
HTML结构:
<!-- 两个固定背景 --> <div class="parallax-bg bg-1"></div> <div class="parallax-bg bg-2"></div> <!-- 长内容,用来滚动 --> <div class="long-content"> <h2>滚动页面切换背景</h2> <p>前半段滚动显示第一张背景,后半段显示第二张,不会重叠~</p> </div>
注意事项
- 滚动驱动动画需要浏览器支持,目前Chrome、Firefox、Edge等主流浏览器已经支持,但移动端部分旧版本可能不兼容。
- 可以调整
animation-range的数值,精确控制每个背景显示的滚动区间。
额外小提示
- 移动端使用
background-attachment: fixed可能会有性能问题或者表现异常,这时候可以通过媒体查询切换为background-attachment: scroll,或者用transform: translateZ(0)开启硬件加速优化。 - 背景图尽量选择高分辨率且适配不同屏幕比例的图片,用
background-size: cover保证显示效果。
内容的提问来源于stack exchange,提问作者jannela vignendra
相关产品推荐
相关产品推荐

