❗ 在 UniApp 的 App 端(尤其是 HBuilderX 3.0+ V3 编译器),
<web-view>默认以「全屏沉浸式」模式渲染,无视 CSS 定位,强制覆盖整个屏幕(包括状态栏区域)。
深层原因分析
1. <web-view> 是原生组件,CSS 定位在 App 端可能被忽略
- 在 H5 或小程序 中,
<web-view>行为接近普通元素,CSS 可控。 - 但在 App 端(Android/iOS),它是原生 WebView 控件,由原生层直接绘制,不完全受前端 CSS 布局控制。
- 尤其当你没有在
pages.json中正确配置导航栏时,系统会默认让web-view全屏。
2. 缺少 pages.json 关键配置
如果你的页面在 pages.json 中使用了默认导航栏(navigationStyle: "default"),但又试图用 CSS 控制 web-view 位置,就会冲突。
终极解决方案(三步走)
第一步:在 pages.json 中 禁用原生导航栏 + 启用沉浸式
// pages.json
{
"path": "pages_act/event5/event",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom", // ← 关键:隐藏原生导航栏
"app-plus": {
"titleNView": false, // 禁用原生标题栏
"immersive": "true" // 沉浸式(允许 webview 延伸到状态栏下)
}
}
}
如果你不加
"navigationStyle": "custom",系统会保留一个透明的原生导航占位,导致布局混乱。
第二步:不要用 CSS 控制 web-view,而是用 plus.webview 原生 API 调整(仅 App)
因为 CSS 在 App 端对 web-view 无效,我们可以用 5+ API 直接操作原生 WebView 的位置。
修改你的 Vue 页面:
<script>
export default {
data() {
return {
loading: true,
statusBarHeight: 0,
// ...其他数据
};
},
onLoad() {
const sysInfo = uni.getSystemInfoSync();
this.statusBarHeight = sysInfo.statusBarHeight || 20;
},
onReady() {
// #ifdef APP-PLUS
this.adjustWebViewPosition();
// #endif
},
methods: {
adjustWebViewPosition() {
// 获取当前页面的 webview
const currentWebview = this.$scope.$getAppWebview();
if (currentWebview) {
// 获取嵌套的子 webview(即 <web-view> 对应的原生 view)
const embeddedViews = currentWebview.children();
if (embeddedViews && embeddedViews.length > 0) {
const webView = embeddedViews[0]; // 第一个子 webview 就是你的 H5
// 设置 top 偏移(单位 px)
webView.setStyle({
top: this.statusBarHeight + 'px',
bottom: '0px'
});
}
}
},
onWebLoad() {
this.loading = false;
// #ifdef APP-PLUS
// 确保加载后也调整一次(有时 onReady 太早)
setTimeout(() => {
this.adjustWebViewPosition();
}, 300);
// #endif
},
// ...其他方法
}
};
</script>
这是 UniApp 官方推荐的 App 端 web-view 精确控制方式。
第三步:确保父容器高度正确
<template>
<view class="container">
<view v-if="loading" class="loading">加载中...</view>
<!-- 注意:web-view 不需要 style 绑定 top 了 -->
<web-view :src="fullUrl" @message="onMessage" @load="onWebLoad" />
</view>
</template>
<style scoped>
.container {
width: 100vw;
height: 100vh;
position: relative;
}
/* App 端靠原生 API 控制位置,这里只做小程序/H5兜底 */
web-view {
/* 小程序/H5 可能需要这个 */
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
补充建议
- 如果你 不需要自定义导航栏,也可以考虑 保留原生导航栏,这样
web-view会自动从导航栏下方开始(但你就不能全屏了)。 - 如果你坚持用 CSS 方案,请确认你使用的是 H5 平台,而不是 App。
总结
要解决 Android 上 web-view 与状态栏重叠问题,必须:
pages.json设置navigationStyle: "custom"- App 端使用
plus.webview原生 API 调整top - 不要依赖 CSS 控制
web-view位置