必须设height: 100vh而非min-height: 100vh,因为锚定视口高度是flex-grow: 1或flex: 1正确分配剩余空间的前提;若用min-height,中间区域无法获得明确可用高度,导致高度为0、滚动失效、页脚错位或body额外滚动。

为什么必须设 height: 100vh 而不是 min-height: 100vh?
顶部固定 + 中间滚动 + 底部固定的布局,核心是让整个容器“锚定视口高度”,而不是“至少撑满”。min-height: 100vh 在内容少时能贴底,但中间区域无法获得明确剩余空间,flex-grow: 1 或 flex: 1 就会失效或计算为 0。
常见错误现象:中间区域高度为 0、滚动条不出现、footer 跑到顶部、整个页面额外出现 body 滚动条。
-
html和body必须设height: 100%且margin: 0,否则100vh容器在部分浏览器(尤其是 Safari)里会被截断 - 根容器(如
.app或.page)要直接设height: 100vh,不能靠继承 - 移动端 Safari 对
100vh的解析受地址栏显隐影响,但此处必须用它——因为滚动逻辑依赖“已知总高”,min-height无法提供确定性空间分配
flex: 1 和 flex-grow: 1 哪个该用?
中间区域必须用 flex: 1(即 flex: 1 1 0),不是 flex-grow: 1。
原因很实际:如果只写 flex-grow: 1,flex-basis 默认是 auto,浏览器会先按内容高度算基准,再放大。当中间区域为空、或含异步加载内容时,初始高度可能为 0,导致 flex-grow 失效或抖动。
-
flex: 1强制flex-basis: 0,真正实现“无视自身内容,纯按剩余空间分配” - 必须同时加
min-height: 0,否则 Flex 子项默认的min-height: auto会阻止它收缩,导致滚动区无法被压缩、overflow-y: auto不触发 - 如果中间区域有嵌套 Flex(比如左右分栏),它的直接子元素也建议加
min-height: 0
滚动条为什么没出现在中间区域?
90% 是因为滚动行为被“上移”到了错误层级:要么加在了根容器上,要么中间区域没真正被限制住。
错误写法:.page { overflow: auto } → 整个页面滚动,header/footer 一起动;.main { height: 100% } → 高度失控,溢出后把滚动权交还给 body。
- ✅ 正确:只在中间区域(如
.main)设overflow-y: auto,且确保它有flex: 1+min-height: 0 - 检查开发者工具中
.main的 Computed Height,要是auto或远大于预期,就说明某个子元素(比如div、table、iframe)偷偷占用了全高 - 禁用子元素的
height: 100vh、min-height: 100vh或height: 100%,改用flex-grow: 1+min-height: 0
footer 为什么被压扁或换行错乱?
Footer 在 Flex column 布局里天然容易被压缩,尤其在窄屏、软键盘弹出、或内容动态插入(如广告 banner)时。
典型表现:文字挤成两行、图标缩放变形、高度从 48px 塌成 24px。
- 底线设置:
flex-shrink: 0—— 防止被 flex 容器挤压 - 避免写
flex: 0 0 auto同时配height,iOS Safari 对这个组合解析异常 - 优先用
min-height而非height,例如min-height: 48px,兼容内容高度波动 - 移动端需预留安全区:
padding-bottom: calc(48px + env(safe-area-inset-bottom)),否则 iPhone 底部按钮会遮挡 footer 文字
html 到 body 到根容器,任何一环的 margin、padding、height 缺失或误设,都会让中间区域失去可计算空间。别只盯着 .main 加 flex: 1,先确认它的父容器有没有被意外截断。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











