最稳方案是CSS中同时使用constant()和env()设置padding-bottom,加在内容容器而非根节点,避免与pages.json的safeArea配置冲突;JS动态获取需在onReady后读取safeAreaInsets.bottom并做兜底处理。
直接用 env(safe-area-inset-bottom) 加内边距最稳
绝大多数场景下,你不需要写 js 计算、也不用改 manifest.json,直接在 css 里用系统提供的环境变量就能解决底部遮挡问题。ios 11.2+ 全面支持 env(),而 uni-app 编译后的 app 和 h5 都能正确读取这个值。
- 必须同时写
constant(safe-area-inset-bottom)(兼容 iOS 11.0–11.1)和env(safe-area-inset-bottom)(iOS 11.2+),只写一个会白屏或错位 - 别用
px硬编码 34rpx——iPhone 12/14 Pro 的灵动岛机型在横屏时safe-area-inset-bottom是 0,竖屏才生效;XR/11 是 34,但 mini 机型可能略小 - 加在「内容容器」上,不是
page根节点:比如.main-content或.page-body,否则可能撑开整个页面导致滚动异常
.main-content {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
pages.json 里配 safeArea.bottom.offset: "auto" 是双刃剑
这个配置看似省事,实际容易引发“多一层 padding”或“和 CSS 冲突”的问题,尤其当你已经手动写了 env()。
- 它只对
app-plus(即打包成 iOS/Android 原生 App)生效,H5 和小程序完全不认这个字段 - 开启后,uni-app 会在页面底部自动插入一个空的
<view></view>占位,高度等于安全区域——如果你的容器本身已有padding-bottom,就会叠加上去,按钮被顶高一截 - 真机测试时发现底部有白条?大概率是它和你写的 CSS 同时生效了。关掉它,只靠 CSS 控制更可控
需要动态控制时,用 uni.getSystemInfoSync().safeAreaInsets.bottom
当你的布局依赖运行时判断(比如横竖屏切换、全屏视频退出后恢复)、或要结合其他逻辑(如弹窗是否避开黑条),就得读取 JS 层的安全区域数据。
-
safeAreaInsets是对象,包含top、right、bottom、left四个数值,单位是 px(不是 rpx),需自行转换单位 - 别在
onLoad里读——部分机型首次加载时safeArea还没就绪;稳妥做法是在onReady或用setTimeout延迟 1 帧再取 - 小程序平台(微信/支付宝)也支持该 API,但返回值单位是 px,且 H5 下为
undefined,务必做兜底:const bottom = systemInfo.safeAreaInsets?.bottom || 0
底部白条/色块不是 bug,是安全区域背景色没覆盖
取消 tabbar 后 iPhone X 出现一块白色横条,不是布局错了,而是 uni-app 默认给安全区域留的空白用了白色背景。它独立于你的页面样式,得单独处理。
- 在
manifest.json的app-plus节点下加"safearea": {"background": "#000000"}可统一改色,但仅限原生 App - H5 或小程序没有这个机制,只能靠 CSS 把容器背景延伸到底部:
min-height: calc(100vh + env(safe-area-inset-bottom)),再配合background-color填满 - 如果用了自定义导航栏(
navigationStyle: "custom"),务必手动加 bottom padding,否则安全区域完全裸露










