如何使用position absolute实现视差滚动?(支持CSS/JS方案)
嘿,我来帮你搞定用position: absolute实现视差滚动的需求!不管是纯CSS的现代方案,还是兼容性更好的JavaScript方案,我都给你梳理清楚了,保证图片滚动时不会被遮挡或者销毁~
纯CSS方案(利用滚动驱动动画)
这个方案用CSS的滚动驱动动画特性(现在主流浏览器都支持啦),不用写一行JS就能实现平滑的视差效果,核心是让绝对定位的图片滚动速度比内容慢。
先完善你的HTML结构:
<div class="container"> <div id="container-of-img-position-absolute"> <img src="your-image.jpg" alt="视差背景图" class="parallax-img"> <span>红色按钮内容</span> </div> <div class="content"> <p>这里是你的内容段落,多写几段让页面能滚动起来...</p> <p>继续添加内容,确保页面高度超过视口,才能看到视差效果</p> <p>更多内容...</p> <!-- 重复p标签直到页面足够长 --> </div> </div>
然后是CSS代码(基于你给出的结构修改):
.container { position: relative; min-width: 100vw; min-height: 100vh; /* 定义滚动时间线,用来驱动动画 */ scroll-timeline: --container-scroll inline; } #container-of-img-position-absolute { position: absolute; top: 0; left: 0; width: 100%; height: 150%; /* 让图片容器比视口高,预留滚动空间 */ overflow: hidden; } .parallax-img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; /* 保持图片比例,避免拉伸 */ z-index: 1; /* 确保图片在内容下方 */ /* 绑定滚动驱动动画 */ animation: parallax linear; animation-timeline: --container-scroll; animation-range: 0 100vh; } /* 定义视差动画:图片移动距离是内容的一半,产生视差感 */ @keyframes parallax { from { transform: translateY(0); } to { transform: translateY(-25%); /* 百分比越小,视差效果越明显 */ } } .content { width: 90%; margin: 50px 5%; background-color: rgba(136, 136, 136, 0.8); /* 加半透明让图片能透出来 */ position: relative; z-index: 3; /* 内容层级最高,不会被遮挡 */ } .content > p { margin-bottom: 20px; padding: 5px 15px; position: relative; z-index: 3; font-size: 1.2rem; line-height: 1.6; } #container-of-img-position-absolute > span { background-color: #F00; padding: 15px 35px; position: absolute; z-index: 2; /* 按钮在图片上方,内容下方 */ top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-weight: bold; }
JavaScript方案(兼容性拉满)
如果需要兼容旧浏览器,或者想要更灵活的控制,就用JS监听滚动事件,动态调整图片位置。
HTML结构和上面一样,CSS简化一下:
.container { position: relative; min-width: 100vw; min-height: 100vh; } #container-of-img-position-absolute { position: absolute; top: 0; left: 0; width: 100%; height: 150%; overflow: hidden; } .parallax-img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1; } .content { width: 90%; margin: 50px 5%; background-color: rgba(136, 136, 136, 0.8); position: relative; z-index: 3; } .content > p { margin-bottom: 20px; padding: 5px 15px; position: relative; z-index: 3; font-size: 1.2rem; line-height: 1.6; } #container-of-img-position-absolute > span { background-color: #F00; padding: 15px 35px; position: absolute; z-index: 2; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-weight: bold; }
然后添加JS代码:
// 获取需要操作的元素 const parallaxImg = document.querySelector('.parallax-img'); // 监听页面滚动事件 window.addEventListener('scroll', () => { // 获取当前滚动距离 const scrollDistance = window.pageYOffset || document.documentElement.scrollTop; // 视差系数:0.5表示图片移动速度是内容的一半,值越小视差越明显 const parallaxRatio = 0.5; // 计算图片需要移动的距离,用transform比直接改top性能更好 const moveY = scrollDistance * parallaxRatio; parallaxImg.style.transform = `translateY(${moveY}px)`; });
几个关键注意点:
- 图片容器
#container-of-img-position-absolute的高度要设置得比视口高(比如150%),这样图片有足够的移动空间,滚动时不会出现空白区域。 - z-index层级一定要理清楚:内容(z-index:3)> 按钮(z-index:2)> 图片(z-index:1),这样不会出现遮挡问题。
- 用
object-fit: cover可以保证图片不会被拉伸变形,保持原有比例。 - JS方案里用
transform而不是top来移动图片,能避免频繁触发浏览器重排,性能更好。
内容的提问来源于stack exchange,提问作者Bambou
相关产品推荐
相关产品推荐

