如何设置scroll-snap-type: mandatory同时支持区域平滑滚动(无JS)
无JavaScript实现混合滚动吸附与平滑滚动
核心思路
把需要吸附的前5个区块和后续平滑滚动区分开,利用scroll-snap的特性:仅对带有scroll-snap-align属性的元素生效,当滚动到无该属性的区域时,自动恢复平滑滚动。
方案一:简洁版(直接在body上设置滚动吸附)
修改后的CSS代码:
body { padding: 0; margin: 0; font-family: sans-serif; scroll-snap-type: y mandatory; /* 主滚动容器开启强制垂直吸附 */ overflow-y: auto; /* 允许body垂直滚动 */ height: 100%; } /* 吸附区块样式 */ .snap-section { min-height: 100vh; scroll-snap-align: start; /* 设置吸附到区块顶部 */ display: flex; flex-direction: column; justify-content: center; background-color: red; } /* 非吸附区块样式 */ .non-snap-section { min-height: 100vh; display: flex; flex-direction: column; justify-content: center; background-color: red; } .longer { min-height: 500vh; background-color: blue; }
对应的HTML结构:
<body> <div class="snap-section">1</div> <div class="snap-section">2</div> <div class="snap-section">3</div> <div class="snap-section">4</div> <div class="snap-section">5</div> <div class="non-snap-section">6</div> <div class="non-snap-section">7</div> <div class="non-snap-section longer">8</div> </body>
方案二:容器拆分版(吸附区与非吸附区分容器)
如果需要给吸附区块统一设置背景或其他容器样式,可采用此方案:
CSS代码:
body { padding: 0; margin: 0; font-family: sans-serif; overflow-y: auto; height: 100%; } /* 吸附容器:高度正好容纳5个100vh区块 */ .snap-container { scroll-snap-type: y mandatory; height: 500vh; background-color: red; } .snap-section { min-height: 100vh; scroll-snap-align: start; display: flex; flex-direction: column; justify-content: center; } /* 非吸附容器 */ .non-snap-container { background-color: red; } .non-snap-section { min-height: 100vh; display: flex; flex-direction: column; justify-content: center; } .longer { min-height: 500vh; background-color: blue; }
HTML结构:
<body> <div class="snap-container"> <div class="snap-section">1</div> <div class="snap-section">2</div> <div class="snap-section">3</div> <div class="snap-section">4</div> <div class="snap-section">5</div> </div> <div class="non-snap-container"> <div class="non-snap-section">6</div> <div class="non-snap-section">7</div> <div class="non-snap-section longer">8</div> </div> </body>
原理说明
- 滚动吸附逻辑:在主滚动容器(方案一的
body、方案二的snap-container)设置scroll-snap-type: y mandatory,强制滚动到带有scroll-snap-align: start的子元素顶部。 - 平滑滚动切换:后续区块移除
scroll-snap-align属性后,滚动容器没有可吸附的目标,自动切换为正常平滑滚动,超长区块也能正常滚动。
内容的提问来源于stack exchange,提问作者YANNTASTIC5915
相关产品推荐
相关产品推荐

