移动端全屏滚动需独立容器设height:100vh、overflow-y:scroll、scroll-snap-type:y mandatory,子项用scroll-snap-align:start且高度为100vh,加touch-action:pan-y,禁用transform/fixed/filter。

直接给 body 或 html 加 scroll-snap-type 基本无效,真正在移动端跑通全屏滑动,必须用独立容器、显式设 overflow-y: scroll 和 height: 100vh,缺一不可。
滚动容器必须“活”起来才能触发吸附
浏览器只对同时满足三个硬性条件的容器启用 scroll snap:
-
height: 100vh(不能是min-height,也不能靠内容撑高) -
overflow-y: scroll(overflow: auto可用但部分安卓 WebView 不稳定;visible或hidden会彻底禁用吸附) -
scroll-snap-type: y mandatory(必须写在这个容器上,不是body)
常见错误是把所有样式堆在 body 上——UA 样式和系统手势策略会绕过 snap 计算。真机测试时若 Timeline 不触发 ScrollStart/ScrollEnd,说明容器根本没“活”起来。
每个子项必须声明 scroll-snap-align 并固定高度
scroll-snap-type 是开关,scroll-snap-align 才是锚点。没它,mandatory 也白搭:
- 全屏垂直滚动统一用
scroll-snap-align: start(顶部对齐),别用center——除非你精确控制了容器与子项高度比 - 子项高度必须是
height: 100vh,不是min-height: 100vh;内容超长时加overflow: hidden或内部滚动,否则吸附基准偏移 - 禁止用
margin-bottom分隔子项——会导致可滚动距离 ≠ 视口高度,松手后卡在两页之间;改用box-sizing: border-box+padding-bottom或负外边距抵消
移动端必须加 touch-action: pan-y
iOS Safari 和 Android Chrome 120+ 默认拦截 touch 事件以优化手势识别,不显式放开就会绕过 snap 逻辑:
- 纵向全屏滚动用
touch-action: pan-y;横向轮播用touch-action: pan-x - 不要写
pan-y pinch-zoom等多值组合——部分 WebView 会因此干扰双指缩放,导致滑动卡顿 -
-webkit-overflow-scrolling: touch已废弃,现代 iOS 不仅不需要,留着还可能冲突,建议删掉
JS 控制切换时别手动算 scrollTop
直接赋值 container.scrollTop = x 在高DPI 屏、缩放页面或 Safari 下极易失步——计算出的像素和实际 snap 点对不上:
- 改用
slideEl.scrollIntoView({ block: 'nearest', inline: 'start' }),它会尊重当前 scroll snap 配置 - 监听
scrollend(Chrome 112+、Safari 16.4+ 支持)做补偿,比监听scroll更可靠;旧版降级用IntersectionObserver,rootMargin设为'0px 0px -50% 0px'提升触发精度
最易被忽略的是:子项一旦用了 transform、position: fixed 或 filter,滚动容器的 overflow 上下文就可能被破坏,吸附瞬间失效——这种问题在真机上才暴露,开发时容易漏测。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











