自定义导航栏遮挡内容的根本原因是未预留顶部空间;启用 navigationstyle: "custom" 后内容从 y=0 开始渲染,需手动通过占位 view 或 padding-top 避让,且三端 statusbarheight 和胶囊高度须动态计算。

自定义导航栏遮挡内容,根本原因是没给页面主体留出足够顶部空间。uni-app 的 navigationStyle: "custom" 会移除原生导航栏,但不会自动帮你推内容下来——你得自己算、自己占位、自己避让。
为什么 content 被遮住?关键在「没预留高度」
启用 navigationStyle: "custom" 后,页面内容默认从屏幕顶部(y=0)开始渲染,而你的自定义导航栏是 position: fixed 或绝对定位覆盖上去的。结果就是:导航栏盖在内容上,而不是“推着内容往下走”。
- 常见错误:只写了一个
<view class="navbar"></view>,没给下面的内容加padding-top或占位<view></view> - 更隐蔽的问题:在 iOS 上用了
statusBarHeight,但没加上胶囊按钮的额外间隙,导致标题/搜索框被微信右上角胶囊遮住 - H5 和 App 端没有胶囊,但如果你统一用胶囊计算逻辑,反而多留了空白
必须动态计算的两个高度:statusBarHeight 和 menuButtonRect
微信小程序需要同时处理状态栏 + 胶囊按钮;H5/App 只需状态栏。硬编码 44px 或 88rpx 在三端必然出错。
-
uni.getSystemInfoSync().statusBarHeight返回真实状态栏高度(iOS 刘海屏约 44px,安卓常见 24–30px,小程序固定 25px) -
uni.getMenuButtonBoundingClientRect()仅微信小程序有效,返回胶囊按钮的{top, height, width}—— 注意top是相对于屏幕顶部的坐标,不是相对于状态栏底部 - 导航栏总高度建议按:
menuButtonRect.top + menuButtonRect.height - statusBarHeight(即胶囊顶部到状态栏底的距离 + 胶囊自身高度),这是最稳妥的“胶囊避让高度” - H5/App 端 fallback 到
statusBarHeight + 44即可,别调用getMenuButtonBoundingClientRect(会报错或返回 null)
页面内容不被遮挡的两种可靠占位方式
核心原则:导航栏是“覆盖层”,内容区域必须主动让出等高空间。
- 方式一(推荐):用空
<view></view>占位,高度 = 导航栏总高度
例如:<view :style="{ height: navbarHeight + 'px' }"></view>,放在自定义导航栏组件下方、页面主内容上方 - 方式二:给主内容容器加
padding-top,值同上
注意:如果内容里有position: absolute元素(比如弹窗、下拉菜单),padding-top不起作用,必须用方式一 - 千万别用
margin-top—— 它会让整个页面产生滚动条空白,尤其在 iOS 上触发 overscroll bounce 时视觉异常
容易被忽略的平台差异点
很多项目上线后才发现:H5 页面顶部多了一截白边,iOS 滚动时导航栏“跳一下”,小程序里搜索框右边被切掉……这些都源于对平台特性的误判。
- 微信小程序:必须用
getMenuButtonBoundingClientRect,且该 API 在真机调试中才返回有效值,模拟器常返回 {top: 0},务必真机验证 - iOS App:
statusBarHeight是安全的,但如果你启用了沉浸式("immersed": true),状态栏会透出内容,此时statusBarHeight可能为 0,需配合plus.navigator.getStatusBarHeight()补充判断 - H5:无胶囊、无状态栏系统级概念,
statusBarHeight始终返回 0,直接按44px或设计稿高度写死更稳 - 所有端都要检查
pages.json中navigationStyle的配置层级:全局设了"custom",就无法在单页改回"default";若只需部分页面自定义,务必只在pages数组内对应项的style中配置











