应改在onLoad或onReady中调用uni.getSystemInfoSync(),H5端statusBarHeight恒为0属正常设计,小程序优先用env.safeArea.top,App端依赖--status-bar-height需确保navigationStyle为custom。

uni.getSystemInfoSync().statusBarHeight 返回 0 怎么办
直接原因是调用时机或平台限制:H5 端本就不提供真实状态栏高度,statusBarHeight 固定返回 0;小程序和 App 端若在 onLoad 前(如 data 初始化、created)调用,也可能拿到 0 —— 此时系统信息尚未就绪。
- 别在
data里硬写默认值,比如statusBarHeight: 20,这会掩盖问题且 H5/Android 失效 - 必须等页面生命周期触发后再读:App 和小程序推荐在
onLoad或onReady中调用uni.getSystemInfoSync() - H5 端完全不用
statusBarHeight,它就是0,这不是 bug,是设计如此 - 如果用了条件编译但逻辑写反(比如把小程序代码包进
#ifdef H5),也会导致取到0
App 端 --status-bar-height 变量没生效
--status-bar-height 是 uni-app 在 App 端注入的 CSS 变量,但它只在 "navigationStyle": "custom" 且页面使用 custom 模式时才可用。如果配置没生效,变量自然为空或未定义。
- 检查
pages.json中该页面是否明确写了"navigationStyle": "custom",全局globalStyle不会覆盖页面级配置 - 确认没被其他插件或原生层拦截,比如某些自定义基座或离线打包方案可能未注入该变量
- 不要在 H5 或小程序环境里依赖这个变量——它在那两个端不保证存在,H5 返回
0,小程序需用env.safeArea.top - 可在样式中加兜底:
height: calc(var(--status-bar-height, 20px) + 44px),避免变量缺失时整个布局崩掉
小程序端 env.safeArea.top 拿不到或为 0
微信/支付宝小程序中,env.safeArea 是最可靠的顶部安全区值,但它必须在 onLoad 之后才能访问。提前读、未开启调试基础库、或未正确触发页面加载,都会导致取到 0 或 undefined。
- 不能在
mounted或created中读uni.getEnv(),必须等onLoad执行完 - 确保基础库版本 ≥ 2.10.4(微信),旧版本不支持
env注入 - 若仍为
0,可 fallback 到uni.getSystemInfoSync().statusBarHeight,但注意这只是状态栏本身,不含胶囊按钮区域 - 胶囊按钮高度固定为
32px,iOS 上状态栏到胶囊间距约6px,Android 约8px,可组合计算导航栏总高:32 + 2 * 6 = 44px(iOS)、32 + 2 * 8 = 48px(Android)
H5 端为什么永远拿不到有效 statusBarHeight
H5 运行在浏览器中,没有系统级状态栏概念。uni.getSystemInfoSync().statusBarHeight 在 H5 返回 0 是正常行为,不是接口异常。强行用它参与布局计算,会导致导航栏贴顶、内容被截断。
- H5 导航栏高度应统一设为
44px,这是 iOS/Android WebView 下视觉最稳定的值 - 不要用
var(--status-bar-height)或env(safe-area-inset-top)做 H5 的顶部偏移,这些在桌面 Chrome 或部分 Android 浏览器里不可靠 - 若用 uView 的
uv-navbar,关掉placeholder属性,自己用padding-top: 44px预留空间 - 三端适配必须用条件编译:
#ifdef APP-PLUS/#ifdef MP-WEIXIN/#ifdef H5,混写一套逻辑必踩坑
真正容易被忽略的是:不同端“导航栏高度”的构成完全不同——App 看 --status-bar-height,小程序看 env.safeArea.top,H5 就只认 44px。试图用一个变量、一个计算公式打遍三端,是绝大多数状态栏问题的根源。


















