错误,grid-template-rows: repeat(n, 100vh) 会导致总高度溢出、iOS Safari 地址栏变化时错位,且浏览器不将其识别为可吸附区域;正确做法是容器设 height: 100vh + scroll-snap-type: y mandatory + overflow-y: scroll,子项设 height: 100vh + scroll-snap-align: start,并清空 body margin。

scroll-snap-type + height: 100vh 是唯一可靠路径
用 grid-template-rows: repeat(n, 100vh) 做全屏翻页是错的——它会把容器撑成 n×100vh,滚动变成“长页惯性滑动”,根本卡不准。真正能实现逐屏吸附的,是让每个子项自己占满视口,并靠 scroll-snap-align 和父容器的 scroll-snap-type 协同工作。
关键结构只有三行 CSS:
-
.scroller容器设display: grid; scroll-snap-type: y mandatory; overflow-y: scroll; height: 100vh; - 每个直接子元素(如
section)设height: 100vh; scroll-snap-align: start; -
body { margin: 0; }必须写,否则首屏顶部多出默认 8px 空白
为什么 grid-template-rows: repeat(n, 100vh) 会失效
这个写法表面看是一屏一行,但实际触发两个硬伤:
- 加了
gap后总高度 = n × 100vh + (n−1) × gap,必然溢出并出现滚动条,破坏“单页”语义 -
100vh是静态计算值,iOS Safari 地址栏收起/展开时不会重算,导致翻页错位甚至跳帧 - 浏览器不把它当“可 snap 区域”,而是当作普通长文档渲染,
scroll-snap-align完全不生效
移动端 iOS Safari 的三个硬约束
写了 scroll-snap-align 却不卡住?大概率卡在这三点:
立即学习“前端免费学习笔记(深入)”;
- 子元素
height不足 100vh:检查是否有margin、padding、border或被flex压缩;建议用box-sizing: border-box统一控制 - 滚动容器不是直接父级:比如导航栏用了
position: fixed,或外层有transform,会切断 snap 链路 - 没设
scroll-behavior: smooth:在html或容器上加这一句,否则吸附过程生硬跳变
响应式重排必须整块重写 grid-template-areas
侧边栏在桌面端在右、移动端要移到主内容下方?不能只调 grid-column 或改列宽。那样会导致区域语义和视觉意图错位,尤其在折叠屏上极易塌方。
正确做法是在媒体查询里整块替换:
/* 桌面 */
.container {
grid-template-areas: "header header" "main sidebar" "footer footer";
}
/* 移动端 */
@media (max-width: 768px) {
.container {
grid-template-areas: "header" "main" "sidebar" "footer";
}
}
真正卡住人的从来不是语法,而是 html/body 的 margin 是否清干净、容器是否真的占满视口、以及响应式断点里有没有整块重写 grid-template-areas。漏掉任意一个,布局就会在某个设备上突然“塌方”。
文章来自机圈观察员网,发布者:,转载请注明出处:https://www.jqgcy.com/xinjizixun/123968.html