--status-bar-height 是跨平台稳定获取状态栏高度的方案,需配置 "navigationstyle": "custom" 且仅 app 和微信小程序支持;h5 不支持,nvue 页面需用 uni.getsysteminfosync;js 中须 onready 后读取并 fallback。

为什么直接用 uni.getSystemInfo().statusBarHeight 不可靠
这个值在不同平台语义不一致:iOS 返回真实像素高度(如 47),Android 多数返回 24 或 25,但全面屏/刘海屏下系统可能动态拉高;H5 和小程序环境甚至不返回该字段。更关键的是,在 App 端 onLoad 阶段调用,常返回 0 —— 此时原生窗口还没完成初始化,getSystemInfo 拿不到有效值。
真正跨平台稳定的方案是 CSS 变量 --status-bar-height,它由 uni-app 在 App 启动时注入,只在 "navigationStyle": "custom" 模式下生效,且已适配各平台实际渲染行为。
- iOS 设备:对应物理状态栏高度(含刘海区域)
- Android 设备:取系统 reported 值,并对齐 webview 渲染边界(非简单 24px)
- 微信小程序:固定为
25px(官方约定,与微信客户端一致) - H5 环境:不支持该变量,需降级处理(如设为
0或用媒体查询兜底)
--status-bar-height 的使用前提和生效条件
这个变量不是全局随时可用的魔法值,它依赖明确的配置链路:
- 必须在
pages.json中对目标页面设置"navigationStyle": "custom" - 仅在 App 端(
APP-PLUS)和微信小程序(MP-WEIXIN)中注入,H5 和其他小程序平台无定义 - nvue 页面不支持该变量,需改用
uni.getSystemInfoSync().statusBarHeight+ style 绑定 - HBuilderX 自带模拟器不触发原生窗口 flags,
--status-bar-height渲染不准,务必真机调试
没配 custom,变量就不存在;配了但跑在 H5 上,var(--status-bar-height) 会计算为 0,导致布局塌陷。
怎么在样式和 JS 中安全读取 --status-bar-height
样式中直接用最稳妥:padding-top: var(--status-bar-height); 或 height: calc(var(--status-bar-height) + 44px); —— 浏览器会自动 fallback 到 0,不会报错。
JS 中读取必须等时机:
- 不能在
onLoad里取,此时 DOM 未就绪、变量未注入 - 应在
onReady后执行:getComputedStyle(document.documentElement).getPropertyValue('--status-bar-height') - 返回值是字符串(如
"47px"),需parseFloat()转数字再参与计算 - 若返回空字符串,说明当前环境不支持该变量(如 H5),应有 fallback 逻辑
常见视觉问题和绕过陷阱
即使用了 --status-bar-height,仍可能遇到内容被遮挡、下拉黑屏、安卓状态栏变灰等问题,本质不是变量错了,而是交互层没约束:
- 下拉刷新开启时,webview 整体拖动,透明导航栏下的内容会顶进状态栏区域 —— 解法是下拉期间临时关闭透明效果,例如加 class:
class="{ 'nav-transparent': !isPulling }" -
<uni-nav-bar></uni-nav-bar>默认带背景色,必须显式绑定:background-color="transparent",否则视觉上“没透明” - 自定义导航栏内放搜索框并聚焦软键盘,键盘顶起会破坏沉浸布局 —— 建议把搜索交互下沉到页面主体,或监听
keyboardHeight动态调整 - 根容器没加
padding-top: var(--status-bar-height),只靠一个<view class="statusBar"></view>占位,滚动时内容仍会滑入状态栏
变量本身很轻量,真正难的是把它的生命周期、平台差异、交互边界全串起来 —— 少一个环节,就卡在“明明写了却没效果”的死循环里。











