




flex布局更健壮:设父容器min-height:100vh、flex-column,main加margin-top:auto推footer到底部;absolute定位需预留空隙且不自适应,仅适用于高度固定场景。
display: flex + flex-direction: column
当页面内容高度不确定,又希望底部始终贴底(不是悬浮)时,flex 是更健壮的选择。关键在于让容器撑满视口,并用 margin-top: auto 推开底部元素。
min-height: 100vh(不是 height: 100vh),否则内容少时底部会被截断header、main、footer;给 main 加 margin-top: auto,它会自动占据剩余空间,把 footer 挤到底部footer 设 flex-shrink: 0 以外的弹性属性,否则在窄屏或小视口下可能被压缩变形.page {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
margin-top: auto;
}
footer {
flex-shrink: 0;
}position: absolute + bottom: 0
适合内容高度已知、或底部不需要随内容伸缩的简单场景。但要注意它脱离文档流,容易和内容重叠。
position: relative,否则 bottom: 0 会相对于视口定位,滚动时 footer 会“粘”在屏幕底部而非页面底部footer 预留底部空隙(如给 main 设 padding-bottom 或 margin-bottom),否则内容会被遮挡.page {
position: relative;
min-height: 100vh;
}
footer {
position: absolute;
bottom: 0;
width: 100%;
}
main {
padding-bottom: 60px; /* 假设 footer 高 60px */
}
判断依据不是“哪个更酷”,而是实际约束条件。
flex,absolute 无法自适应高度变化flex 天然支持,absolute 需配合 JS 计算高度,得不偿失flex-grow: 1,部分老 Safari 对简写解析异常这是 iOS Safari 的视口缩放行为导致的:地址栏收起/展开时触发 resize,100vh 值突变,flex 容器高度重排,视觉上像 footer 跳动。
min-height: 100dvh 替代 100vh(dvh 是动态视口单位,iOS 16+ 支持)resize,动态设置 style.minHeight = window.innerHeight + 'px',但注意节流height: 100vh —— 它在地址栏变化时不会重绘,反而导致 footer 悬空或截断flex 布局的底层逻辑是分配空间,绝对定位的底层逻辑是脱离流定位;选错方案本身不致命,但忽略视口单位差异、父容器定位上下文、或内容高度不确定性,就很容易在真实设备上出问题。