flex实现底部栏固定的关键是让父容器撑满视口并采用column布局,通过main设margin-top: auto或flex: 1将footer自然推至底部,而非依赖fixed定位。

用 Flex 实现底部栏始终固定在页面底部,核心不是“固定定位”,而是让容器撑满视口、内容区域主动占位,把底部栏自然推到最底。关键不在 footer 本身怎么写,而在它所处的上下文是否满足 flex 布局的空间分配前提。
必须设好高度基准:html 和 body 要清空并撑满
浏览器默认 body 高度由内容决定,不占满屏幕。footer 想沉底,父容器就得有“可分配的高度”。这一步出错,后面全白搭:
- 给 html 和 body 设
margin: 0; padding: 0;,清除默认边距干扰 - 给它们加
min-height: 100vh;(不是height: 100vh,否则内容超长会被截断) - 不要直接在
body上写display: flex—— Safari 等旧浏览器支持不稳定,建议包一层.app或.page
外层容器要用 column flex,并确保 footer 是直接子元素
把布局逻辑放在一个稳定可控的 wrapper 上,结构清晰、兼容性好:
- 包裹层(如
<div class="app">)设 <code>display: flex; flex-direction: column; min-height: 100vh; - 内部元素顺序必须是:
<header></header>→<main></main>→<footer></footer>,三者同级且都是 wrapper 的直接子元素 - footer 不能嵌套在 main 里,也不能被其他 div 包裹——否则它就脱离了 flex 主轴,
margin-top: auto或flex: 1失效 -
给
main加margin-top: auto:利用 flex 中 auto margin 的“吸顶”特性,把 main 尽量往上贴,剩余空间自动留给 footer。轻量、干扰小、DOM 更干净 -
给
main加flex: 1:让 main 主动伸展,吃掉 header 和 footer 之外的所有可用高度。适合内容区需滚动填满、且希望高度严格受控的场景 - 无论选哪种,
footer本身都不需要设flex、height或flex-shrink: 0(除非你明确要防压缩,比如含图片的页脚) - 现代浏览器可用
100dvh替代100vh,它能随动态视口实时更新(iOS 16.4+/Chrome 105+ 支持) - 兼容旧环境需 JS 监听
resize,或在键盘收起后手动触发window.scrollTo(0, 0)重绘 - 避免同时给 footer 设
height和margin-top: auto,Safari 某些版本会算错剩余空间,导致 main 塌缩
推 footer 到底的两种主流方式,推荐 margin-top: auto
二者都有效,但行为和适用场景不同:
移动端和动态内容要额外留意视口变化
纯 CSS 无法响应软键盘弹出、地址栏缩放、异步加载后高度突变等场景,这时 min-height: 100vh 会失效,footer 浮起来:











