直接用 position: fixed; bottom: 0 不够用,因 fixed 元素脱离文档流不占空间,必须为 body 设置 padding-bottom(如 56px 或 calc(56px + env(safe-area-inset-bottom)))兜底避让,否则正文末行必被遮挡。

直接用 position: fixed,但必须配 padding-bottom 防遮挡,否则正文最后一行大概率被盖住。
为什么 position: fixed; bottom: 0 不够用
它只让元素“贴在视口底边”,但不会自动给正文腾地方。滚动到底部时,文字、按钮、表单控件会钻进栏下面,用户点不到、看不清。这不是 bug,是 CSS 脱离文档流的必然结果。
- 安卓 WebView 和 iOS Safari 行为一致:fixed 元素不参与布局计算
- 如果底部栏高
56px,正文容器没留空,那第n行内容就从56px处开始渲染,刚好被盖住 - 某些微信 iOS 客户端(如 8.0.32 之前)还会忽略
viewport-fit=cover,导致安全区适配失效
body 上加 padding-bottom 是最稳的解法
不是加在底部栏上,也不是加在 main 上——而是直接作用于 body,确保整个页面内容区天然避开固定栏。
- 若栏高固定为
56px,写body { padding-bottom: 56px; } - 要兼容 iPhone 底部 Home Indicator,先加
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">,再写body { padding-bottom: calc(56px + env(safe-area-inset-bottom)); } - 低版本 Safari(15.4 之前)不支持
calc()里混用env(),可降级为两行:padding-bottom: 56px;和padding-bottom: calc(56px + env(safe-area-inset-bottom));(后一条会覆盖前一条)
底部栏自身的样式不能漏三件套
只写 bottom: 0 是不够的,缺任意一项都可能在缩放、横屏或小屏下错位。
立即学习“前端免费学习笔记(深入)”;
- 必须同时声明
position: fixed; bottom: 0; left: 0; right: 0; - 高度用固定值(如
height: 56px),别用100vh或百分比——Safari 地址栏收放时会跳变 -
z-index: 999足够,设成99999容易和弹窗、modal 的层级冲突 - 避免在栏内放
<input>或<textarea>,iOS 键盘弹出后 fixed 元素常错位
DOM 位置必须在 <body> 最末尾
有些框架或 CMS 会把脚本、统计代码塞在 </body> 前,但底部栏的 <div class="bottom-nav"> 必须是 <body> 的最后一个子节点。
- 部分安卓 WebView 对父容器
overflow敏感,如果栏被包在某个div里且该div有transform或overflow: hidden,fixed 会失效 - 不要用
margin-top: auto或flex: 1模拟“沉底”,那是给真页脚(footer)用的,不是悬浮栏 - 如果导航项需要点击切换状态,交互逻辑必须用 JS 实现;纯 CSS 只能定位,不能管理选中态或防重复创建
真正麻烦的不是写几行 CSS,而是所有兼容性细节得一起到位:viewport meta、padding 计算、DOM 顺序、键盘交互避让——漏掉任意一环,用户在某台手机上就会点不到那个按钮。



















