如何让堆叠区块中的.square元素始终处于顶层?
问题与解决方案
我希望.square div始终处于顶层,实现视觉上带有自身.square的下一个section向上滑动时,新的.square能精准停在上一个section的.square位置。现有代码实现了滑动对位效果,但下一个section向上滑动时会覆盖上一个section的.square,尝试设置z-index无效,该如何解决?
问题原因
当section被设置为sticky后,会创建独立的堆叠上下文。.square的z-index仅在其父section的堆叠上下文内生效,后续的sticky section会自然堆叠在前面的section之上,导致其背景覆盖前一个section的.square。
解决方法
核心思路:为激活的sticky section设置更高层级
通过调整CSS和JS,让当前处于sticky状态的section拥有更高的z-index,确保其内部的.square始终处于顶层:
1. 修改CSS基础样式
给所有.make-sticky设置基础z-index,同时为激活状态的.sticky-section设置更高的z-index:
.scrollable { border: 5px solid red; position: relative; .make-sticky { position: relative; height: 100vh; padding: 20px; box-sizing: border-box; z-index: 1; /* 基础层级,确保非激活section的堆叠顺序 */ .line { position: absolute; left: 20px; top: 0; bottom: 0; width: 2px; background: black; } .square { position: absolute; left: 10px; width: 20px; height: 20px; background: transparent; border: 2px solid red; top: 25%; z-index: 1; } p { margin-top: 50vh; } &.sticky-section { position: -webkit-sticky; position: sticky; top: 0; z-index: 10; /* 激活时的更高层级,确保当前section内容在顶层 */ } } }
2. 优化JS实现精准层级控制(可选)
如果需要更精细的层级管理(比如让后续激活的section层级依次递增,避免多个sticky section叠加时的覆盖问题),可以修改IntersectionObserver的回调逻辑:
$(document).ready(function() { const sections = document.querySelectorAll('.make-sticky'); // 为每个section设置初始z-index,按顺序递增 sections.forEach((section, index) => { section.style.zIndex = index + 1; }); const observer = new IntersectionObserver(entries => { entries.forEach(({ target, isIntersecting }) => { if (isIntersecting) { $(target).addClass('sticky-section'); // 激活时设置最高层级,确保当前section内容在所有section之上 target.style.zIndex = sections.length + 1; } else { $(target).removeClass('sticky-section'); // 恢复初始层级,保证非激活section的正常堆叠顺序 const index = Array.from(sections).indexOf(target); target.style.zIndex = index + 1; } }); }, { root: null, rootMargin: '0px', threshold: 0.1 }); sections.forEach((section) => { observer.observe(section); }); });
完整可运行代码示例
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.2/jquery.min.js"></script> <div class="scrollable"> <section class="make-sticky" style="background: cyan" id="section1"> <div class="line"></div> <div class="square"></div> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. 1111111111111111111111 Esse tempora facere beatae, harum voluptatibus eveniet explicabo corporis suscipit error sit nostrum minima ducimus, perspiciatis aperiam blanditiis labore iure quidem est.</p> </section> <section class="make-sticky" style="background: salmon" id="section2"> <div class="line"></div> <div class="square"></div> <p>Quod magni natus dignissimos, voluptate incidunt ddddddddddddddddddddddddddddd reiciendis culpa labore nihil veritatis quasi eum exercitationem, laboriosam impedit tenetur deleniti itaque? Velit atque provident labore corrupti libero eius nostrum. Distinctio, qui pariatur?</p> </section> <section class="make-sticky" style="background: yellowgreen" id="section3"> <div class="line"></div> <div class="square"></div> <p>Quod magni natus dignissimos, voluptate incidunt 222222222222222222222222 reiciendis culpa labore nihil veritatis quasi eum exercitationem, laboriosam impedit tenetur deleniti itaque? Velit atque provident labore corrupti libero eius nostrum. Distinctio, qui pariatur?</p> </section> <section class="make-sticky" style="background: orange" id="section4"> <div class="line"></div> <div class="square"></div> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. 3333333333333333333333333333 Esse tempora facere beatae, harum voluptatibus eveniet explicabo corporis suscipit error sit nostrum minima ducimus, perspiciatis aperiam blanditiis labore iure quidem est.</p> </section> <section class="make-sticky" style="background: blue" id="section5"> <div class="line"></div> <div class="square"></div> <p>Quod magni natus dignissimos, voluptate 4444444444444444444444444444 incidunt reiciendis culpa labore nihil veritatis quasi eum exercitationem, laboriosam impedit tenetur deleniti itaque? Velit atque provident labore corrupti libero eius nostrum. Distinctio, qui pariatur?</p> </section> </div>
CSS
.scrollable { border: 5px solid red; position: relative; .make-sticky { position: relative; height: 100vh; padding: 20px; box-sizing: border-box; z-index: 1; .line { position: absolute; left: 20px; top: 0; bottom: 0; width: 2px; background: black; } .square { position: absolute; left: 10px; width: 20px; height: 20px; background: transparent; border: 2px solid red; top: 25%; z-index: 1; } p { margin-top: 50vh; } &.sticky-section { position: -webkit-sticky; position: sticky; top: 0; z-index: 10; } } }
JS
$(document).ready(function() { const sections = document.querySelectorAll('.make-sticky'); sections.forEach((section, index) => { section.style.zIndex = index + 1; }); const observer = new IntersectionObserver(entries => { entries.forEach(({ target, isIntersecting }) => { if (isIntersecting) { $(target).addClass('sticky-section'); target.style.zIndex = sections.length + 1; } else { $(target).removeClass('sticky-section'); const index = Array.from(sections).indexOf(target); target.style.zIndex = index + 1; } }); }, { root: null, rootMargin: '0px', threshold: 0.1 }); sections.forEach((section) => { observer.observe(section); }); });
内容的提问来源于stack exchange,提问作者Greg Bialowas
相关产品推荐
相关产品推荐

