iPhone X+ 底部安全区需用 env(safe-area-inset-bottom) 配合 padding-bottom 或 height 适配,配合 viewport-fit=cover,并通过 @supports 降级、JS 辅助判断及 class 封装保障兼容性。

iPhone X+ 系统底部安全区导致导航栏被遮挡
直接加 position: fixed; bottom: 0; 在 iPhone X 及后续机型上,导航栏会卡在屏幕最底、被圆角和 Home 指示条遮住——这不是 CSS 写错了,是系统没给留空间。iOS 11+ 提供了 env() 函数来读取安全区偏移,关键变量是 safe-area-inset-bottom。
env(safe-area-inset-bottom) 必须配合 padding-bottom 或 height 使用
不能只靠 bottom 值去“顶”出来,得把内容区域本身撑开,让固定定位的容器有足够空间落脚。常见错误是写成 bottom: env(safe-area-inset-bottom);,这反而会让导航栏上移、露出空白。
- 正确做法:给导航栏容器设
padding-bottom: env(safe-area-inset-bottom);,同时保持bottom: 0; - 如果导航栏高度固定(比如 60px),更稳妥的是用
height: calc(60px + env(safe-area-inset-bottom));,再配padding-bottom: env(safe-area-inset-bottom);防止内部按钮贴边 - 必须加
viewportmeta 支持:,否则env()返回 0
Android 和旧 iOS 版本要降级兜底
env() 在 Android 浏览器(包括 Chrome)和 iOS 10 及以下不支持,直接用会失效。不能依赖 JS 检测,CSS 层面就得写两套。
- 先写降级样式:
padding-bottom: 12px;(常见安卓底部导航高度参考值) - 再用
@supports (padding-bottom: env(safe-area-inset-bottom))包裹增强样式,覆盖前面的值 - 避免用
min-height替代height,某些 WebView 对env()解析不稳定,min-height可能不触发重绘
微信内置浏览器里 env() 表现不一致
部分版本微信(如 8.0.3x–8.0.4x)对 env(safe-area-inset-bottom) 返回值异常(有时为 0,有时为 34px 却不更新),单纯依赖它会导致导航栏忽高忽低。
- 加一层 JS 判断是否真有安全区:
if ('screen' in window && screen.height - window.innerHeight > 50)(粗略识别刘海屏) - 结合 class 控制:
document.documentElement.classList.add('has-safe-area'),再写.has-safe-area .nav-bar { padding-bottom: env(safe-area-inset-bottom); } - 真遇到极端情况,宁可手动设死值
padding-bottom: 34px;,也比错位强
实际适配最麻烦的不是写法,而是不同微信版本、不同系统补丁、不同 WebView 内核对 env() 的解析节奏不一致——测的时候好好的,发版后某一批用户就出问题。建议把安全区逻辑封装成独立 class,和业务样式解耦,方便灰度替换。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











