position: fixed 实现底部导航栏必须手动预留空间,因该定位使元素脱离文档流,主内容会自然“长入”其下方;须用 margin-bottom 或 padding-bottom 配合 calc(var(--nav-height) + env(safe-area-inset-bottom)) 并设置 viewport-fit=cover 才能正确适配安全区。

直接用 position: fixed 是最常用也最容易出问题的方案——主内容会钻进导航栏下面,滚动时文字被盖住,软键盘弹出后布局错位。别指望浏览器自动留空,必须手动干预。
为什么 fixed 导航栏总遮住主内容?
因为 position: fixed 让元素完全脱离文档流,浏览器渲染时根本“看不见”它。主内容从视口底部开始绘制,自然长进导航栏下面。这不是 bug,是 CSS 规范行为。
- 必须给主内容容器(比如
<main></main>)加margin-bottom,或给加padding-bottom -
margin-bottom更推荐:不影响scrollHeight,也不干扰IntersectionObserver等 API 的判断 - 值不能硬写
60px,得包含真实导航高度 + 安全区偏移,例如:calc(60px + env(safe-area-inset-bottom)) - 但 Safari 15.4 之前不支持在
calc()里混单位,得拆成两条声明:margin-bottom: 60px;margin-bottom: calc(60px + env(safe-area-inset-bottom))
iPhone X+ 手势条盖住按钮怎么办?
只写 bottom: 0 会让导航沉进系统手势条里,用户点不到。关键不是调位置,而是显式预留安全区空间。
- 必须在
中加:<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">,否则env(safe-area-inset-bottom)返回0 - CSS 写法要兼容旧版 iOS:
padding-bottom: constant(safe-area-inset-bottom);padding-bottom: env(safe-area-inset-bottom) - 安卓和旧 iOS 会忽略
env(),自动 fallback 为0,无副作用
导航项怎么等宽又不被压缩?
flex: 1 在按钮内或文字长度不一时容易失效,iOS Safari 对 flex: 1 在 <button></button> 里表现尤其不稳定。
- 导航容器设
display: flex,子项用flex: 0 0 20%(五格就写20%),比flex: 1更可控 - 加
min-width: 0防止文字撑开导致宽度不均 - 避免用
justify-content: space-around——它依赖父容器有明确宽度,而fixed容器默认没宽度约束,容易在某些 UA 下错位
真正难的不是写几行 fixed 和 flex,而是理解「安全区」不是可选适配,而是 iOS 布局计算的硬边界;env(safe-area-inset-bottom) 不是装饰性变量,而是必须参与尺寸计算的布局因子。漏掉 viewport-fit=cover 或把两条 padding-bottom 声明合并成一条 calc(),都会让 iPhone 用户点不到最后一个图标。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











