用 scroll-snap-type + scroll-snap-align 可实现全屏翻页,但需严格设置 overflow-y: scroll、overflow-x: hidden、固定高度(如 100vh)、scroll-snap-align: start,并处理 iOS/Safari 兼容性及微信 X5 内核降级。
直接用 scroll-snap-type + scroll-snap-align 就能实现接近原生体验的全屏上下翻页,但默认行为在 iOS Safari 和部分安卓 WebView 中容易卡顿或跳过页面,必须配合特定布局约束和滚动容器修正。
overflow-y: scroll 且禁用 overflow-x
很多开发者用 overflow: auto 或 overflow: scroll,结果在 iOS 上失效——Safari 要求明确指定 overflow-y 才触发 scroll snap。同时,overflow-x 必须显式设为 hidden,否则横向滚动干扰 snap 判定。
height 或 max-height 必须固定(如 100vh),不能依赖 min-height 或内容撑开-webkit-overflow-scrolling: touch(iOS 15+ 已非必需,但保留更稳)transform、filter 等触发合成层的属性,否则 snap 可能被忽略scroll-snap-align: start 并占满视口高度抖音式翻页本质是「每页强制对齐顶部」,所以所有子项统一用 scroll-snap-align: start。关键点在于:每个区块必须严格等于容器高度(含 border/padding 影响),否则 snap 目标错位。
flex: 0 0 100vh 或 height: 100vh,而非 min-height: 100vh
100vh 中减去它们的高度,否则超出导致多页可见vh 而非 100%,后者在地址栏展开/收起时会跳变scroll-behavior: smooth 不够scroll-behavior: smooth 在 Safari 上对 snap 无效,且无法控制减速曲线。真实场景中,快速滑动后常停在两页之间,需靠 JS 补偿。
立即学习“前端免费学习笔记(深入)”;
scrollend 事件(Chrome 112+、Safari 16.4+ 支持),手动 scrollTo 到最近 snap 点scroll,用 getBoundingClientRect().top 计算偏移,阈值判断后 scrollIntoView({ block: 'start', behavior: 'smooth' })
scrollIntoView 会导致二次跳动iOS 15.4 是首个稳定支持 scroll-snap-type 的版本,之前版本即使写了也无效果。单纯靠 CSS 会白屏或滚动失控。
@supports (scroll-snap-type: y mandatory) 区分支持环境touchmove + scrollTop 计算 + requestAnimationFrame 模拟 snap最易被忽略的是 viewport 单位在 iOS 竖屏地址栏变化时的重绘问题——100vh 会突然变矮,导致当前页被截断。解决方案不是 JS 动态改 height,而是用 env(height: 100vh) 或 CSS lh 配合伪元素占位,但这些细节一旦漏掉,用户一滑就出 bug。