最常踩的坑是父容器未设position: relative或未预留padding-bottom:absolute footer会相对于最近定位祖先定位,若无则回退至body/html,导致脱离文档流叠盖内容;必须同时满足html/body设height: 100%、容器设position: relative+min-height: 100%、并加padding-bottom: [footer高度]且box-sizing: border-box。

用 min-height + position: absolute 时为什么 footer 会遮住内容?
这是最常踩的坑:父容器没设 position: relative,或没预留 padding-bottom 空间。浏览器把 position: absolute; bottom: 0 的 footer 相对于最近的定位祖先计算位置——如果祖先没定位,就往上找,最终可能相对于 body 或 html 定位,而它们默认不是定位元素,导致 footer 脱离文档流后直接叠在内容上。
必须同时满足三个条件:
-
html和body高度设为100%(不能只设min-height) - 包裹
header+main+footer的容器(比如#container)设position: relative且min-height: 100% - 该容器还要加
padding-bottom: [footer高度],并配box-sizing: border-box,否则padding会额外撑高容器
Flex 布局中 flex: 1 为什么必须写在 main 上,而不是 section 或 div?
因为 flex: 1 是对 flex 容器的**直接子元素**生效的。如果你把 display: flex; flex-direction: column 加在 body 上,那只有 header、main、footer 这三个兄弟节点能参与 flex 分配;中间再套一层 div,它就变成 main 的子元素,不再受 body 的 flex 控制。
常见错误写法:
body { display: flex; flex-direction: column; }
main { flex: 1; } /* ✅ 正确:main 是 body 的直接子元素 */
但如果你这样写:
<main><div class="wrapper">...</div> </main>
然后给 .wrapper 设 flex: 1 —— 它完全无效,因为它的父元素 main 并不是 flex 容器。
min-height: calc(100vh - Xpx) 在移动端为什么有时失效?
因为 iOS Safari 和部分安卓 WebView 中,vh 单位在地址栏显示/隐藏时会重算,导致页面“跳动”;更严重的是,当页面有 input 聚焦弹出软键盘时,视口高度突变,100vh 可能变成远小于真实可视区域的高度,造成底部被截断。
更稳妥的做法是不用 vh,改用 min-height: 100% 配合 flex 或 grid。例如:
html { height: 100%; }
body {
min-height: 100%;
display: flex;
flex-direction: column;
}
main { flex: 1; }
这套组合不依赖视口单位,也不受软键盘影响,兼容性也覆盖到 IE11+。
Grid 方案里 grid-template-rows: auto 1fr auto 的 1fr 到底占谁的剩余空间?
它占的是 body(或你指定的 grid 容器)的可用高度减去 auto 行之后的剩余空间。关键点在于:auto 行高度由内容决定,1fr 行会拿走所有“剩下的”,哪怕内容为空,它也会撑开整个容器,从而把 footer 推到底部。
容易忽略的细节:
- 必须确保
body有明确高度来源(如min-height: 100vh或height: 100%) -
header和footer不能设position: absolute或fixed,否则它们脱离文档流,grid 就无法识别其高度,auto就会塌成 0 - 如果
header内用了margin-bottom: -60px这类负边距技巧,grid 仍按原始盒模型计算高度,可能导致布局错乱
实际项目里,Flex 方案最省心:结构清晰、语义自然、无计算误差、软键盘下稳定。Grid 更适合需要精确控制多行/多列的复杂页脚场景。Min-height + absolute 那套,现在只建议用于 legacy IE 兼容兜底,别在新项目里主动选。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











