app端唯一稳解是css变量var(--status-bar-height),需navigationstyle: "custom"且禁用titlenview;小程序端优先用env.safearea.top,fallback用statusbarheight加补偿;h5端固定44px。

直接用 var(--status-bar-height),别自己算、别 JS 读、别条件编译绕弯——但仅限 App 端;小程序和 H5 必须换路子。
App 端:CSS 变量是唯一稳解,navigationStyle: "custom" 是前提
App 端的 var(--status-bar-height) 由 uni-app 运行时注入,已适配 iOS 刘海、安卓挖孔、华为/小米等厂商定制屏,比 JS 调 uni.getSystemInfoSync() 准确得多——后者在 onLoad 阶段常返回 0,因为 DOM 和原生窗口尚未就绪。
- 必须在
pages.json对应页面的style节点(或globalStyle)里设"navigationStyle": "custom",否则变量不生效 - 同时设
"titleNView": false,否则原生导航栏仍占位,custom形同虚设 - 根容器加
padding-top: var(--status-bar-height)即可占位,别用margin-top,避免滚动错位 - 真机调试必须用正式打包的 IPA/APK,HBuilderX 模拟器不触发原生窗口 flags,
--status-bar-height渲染不准
小程序端:不能信 statusBarHeight,得靠 env.safeArea.top
微信/支付宝小程序里,uni.getSystemInfoSync().statusBarHeight 返回的是纯状态栏高度(通常 25px),但实际「状态栏 + 导航栏容器」占用高度可能是 88px~96px(尤其 iOS 15+ 的阴影和内边距)。直接用它会导致自定义导航栏上移、内容被截断。
- 必须等
onLoad触发后访问uni.getEnv()或getSystemInfo,created/mounted阶段env尚未注入 - 优先读
env.safeArea?.top,它是小程序容器计算出的真实安全区顶部偏移 - fallback 方案:若
env.safeArea不存在(极少数旧版),再取statusBarHeight,但需手动加 44px~60px 补偿导航栏容器 - 胶囊按钮位置还得额外调
uni.getMenuButtonBoundingClientRect(),不能只靠 top 值
H5 端:--status-bar-height 是个假变量,固定写死 44px
H5 运行在浏览器中,没有系统状态栏概念,var(--status-bar-height) 编译后值恒为 0。抄 App 或小程序的写法,必然导致导航栏贴顶、内容被截、iOS Safari 下布局崩塌。
- H5 导航栏高度统一用
44px,这是主流 WebView(iOS Safari / Android Chrome)视觉最协调的值 - 不要在 data 里异步赋值
navHeight,uni.getSystemInfoSync()在 H5 返回 0 或undefined,且样式渲染早于 JS 回调 - 用条件编译隔离:
// #ifdef H5块里写height: 44px; padding-top: 0;,// #ifdef APP-PLUS块里才用var(--status-bar-height) - 若用了 UI 库(如 uView 的
uv-navbar),关掉其placeholder属性,自己用padding-top: 44px控制留白
最容易被忽略的其实是平台边界:App 端的 CSS 变量、小程序端的 env.safeArea、H5 端的固定值,三者逻辑互斥,混用必出问题。别想着“一套代码跑三端”,得在编译期就切开,而不是 runtime 里 if-else 判定。











