滚动时如何实现元素触底后固定且内容可滚动?
解决方案:可滚动内容的粘性Section效果
问题说明
需要实现Section依次固定的效果,但每个Section内部内容支持滚动——仅当Section底部到达视口时才触发固定。当前代码中,当Section高度设为200vh时,前两个Section会直接固定在顶部,无法滚动查看内部内容,仅最后一个Section表现正常。
纯CSS实现方案
通过给每个Section包裹固定高度的容器,结合sticky定位实现需求,无需JavaScript。
代码示例
HTML
<div class="section-wrap"> <section> <img src="https://picsum.photos/id/128/800/300" alt=""> </section> </div> <div class="section-wrap"> <section> <img src="https://picsum.photos/id/48/800/300" alt=""> </section> </div> <div class="section-wrap"> <section> <img src="https://picsum.photos/id/42/800/300" alt=""> </section> </div>
CSS
/* 每个Section的容器,占满一屏高度,控制固定触发时机 */ .section-wrap { height: 100vh; } section { position: sticky; bottom: 0; /* 当容器滚到视口底部时,Section固定在视口底部 */ height: 200vh; overflow-y: auto; /* 允许内部内容滚动 */ } section img { width: 100%; height: 100%; object-fit: cover; } section:nth-of-type(1) { background: rgb(225, 204, 200); } section:nth-of-type(2) { background: rgb(240, 216, 163); } section:nth-of-type(3) { background: rgb(192, 211, 217); }
原理说明
section-wrap设置为100vh,确保每个Section的“固定触发点”在视口底部位置。- Section使用
position: sticky+bottom: 0,在容器滚动过程中会随页面移动,直到容器底部到达视口,此时Section固定在视口底部。 overflow-y: auto让Section内部内容在高度超过视口时可以滚动。
JavaScript实现方案
适合需要更灵活布局的场景(例如容器高度不固定),通过监听滚动事件动态控制Section的固定状态。
代码示例
HTML
<section> <img src="https://picsum.photos/id/128/800/300" alt=""> </section> <section> <img src="https://picsum.photos/id/48/800/300" alt=""> </section> <section> <img src="https://picsum.photos/id/42/800/300" alt=""> </section>
CSS
section { height: 200vh; } section img { width: 100%; height: 100%; object-fit: cover; } /* 固定状态的样式 */ section.fixed { position: fixed; top: 0; left: 0; right: 0; height: 100vh; overflow-y: auto; } section:nth-of-type(1) { background: rgb(225, 204, 200); } section:nth-of-type(2) { background: rgb(240, 216, 163); } section:nth-of-type(3) { background: rgb(192, 211, 217); }
JavaScript
const sections = document.querySelectorAll('section'); // 最后一个Section无需固定,保持默认布局 sections[sections.length - 1].style.position = 'static'; window.addEventListener('scroll', () => { sections.forEach((section, index) => { if (index === sections.length - 1) return; const rect = section.getBoundingClientRect(); // 判断Section底部是否完全进入视口 const isBottomInView = rect.bottom <= window.innerHeight; if (isBottomInView) { section.classList.add('fixed'); // 禁止页面滚动,避免影响固定Section的内部滚动 document.body.style.overflow = 'hidden'; } else { section.classList.remove('fixed'); // 检查是否还有固定的Section,没有则恢复页面滚动 if (!Array.from(sections).some(s => s.classList.contains('fixed'))) { document.body.style.overflow = 'auto'; } } }); });
原理说明
- 监听页面滚动事件,计算每个Section的位置,判断其底部是否进入视口。
- 当Section底部进入视口时,添加
fixed类将其固定在视口顶部,同时禁止页面滚动,让内部内容可独立滚动。 - 当滚动到下一个Section时,移除上一个Section的固定类,恢复页面滚动。
内容的提问来源于stack exchange,提问作者cak3_lover
相关产品推荐
相关产品推荐

