刘海屏设备下全屏背景总被状态栏遮挡怎么办?

西门子诺 阅读 43

最近在做全屏背景图的时候发现,iPhone 14 Pro的刘海区域总会有一块地方显示不出来,用safe-area-inset设置的padding反而把内容推下去了,但背景图还是被刘海遮住了一角。

试过这样写CSS:


body {
  margin: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);
  padding: 0;
  min-height: calc(100vh - env(safe-area-inset-top) - env(safe-area-inset-bottom));
}

结果底部导航栏区域出现了滚动条,而且背景图的fixed定位元素还是贴到刘海下面去了。查了文档说是需要同时处理padding和定位,但具体怎么组合才能兼容Android和iOS的刘海屏呢?

我来解答 赞 15 收藏
二维码
手机扫码查看
2 条解答
一素香
一素香 Lv1
这问题我太熟了,当年做移动端主题的时候踩过一堆坑,现在WP里做全屏背景图,核心思路是别让body直接占满100vh,得把safe area的逻辑拆开处理。

首先你那个写法问题在——min-height: calc(100vh - env(...))这句会让页面实际高度变小,但background-attachment: fixed的元素还是按视口尺寸定位,所以它还是贴到刘海底下去了。

正确姿势是:给一个包层容器做全屏背景,body保持默认,用JS动态加safe-area-inset的padding到这个容器上,或者用CSS的padding-top: env(safe-area-inset-top)配合position: sticky的header规避滚动问题。

最稳妥的WP开发写法是这样:

先在主题里用wp_add_inline_style动态注入safe-area变量,或者直接在header里加个meta标签让iOS识别safe area:



然后CSS这么写:

.full-screen-bg {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-size: cover;
background-position: center;
z-index: -1;
}

/* 给内容容器加内边距避开刘海 */
.site-content {
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
min-height: 100vh;
box-sizing: border-box;
}


注意body别设min-heightheight: 100%,WP主题里很多默认样式会冲突,最好用wp_reset_query之后再测。

如果用的是自定义主题,建议把背景图包在一个<div class="full-screen-bg">里,别直接用body或html标签,不然WordPress的编辑器、管理员工具栏(admin bar)一出来就全乱套了,这个坑我踩过不止一次。

Android大部分没问题,但华为那些挖孔屏偶尔会把100vh算错,所以稳妥点还是加个JS兜底:

if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
var topInset = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--safe-area-inset-top') || '0');
document.querySelector('.full-screen-bg').style.top = topInset + 'px';
}


不过现在iOS 15+基本不用JS了,只要viewport-fit=cover加上上面那个CSS写法,99%的刘海屏都能覆盖。
点赞 3
2026-02-23 21:12
慕容永伟
你这个问题我也踩过坑,根本原因是只用了 env(safe-area-inset-top) 控制 margin 或 padding,但没处理 fixed 元素的定位逻辑。背景图如果用的是 position: fixed; top: 0;,那它一定会从屏幕最顶上开始渲染,刘海区域自然就被切了。

正确做法是让全屏容器本身避开安全区影响,同时保证内容和背景都能完整覆盖可视窗口。

先改 HTML 结构,加个根层容器:

<div class="full-screen-layout">
<div class="bg-image"></div>
<div class="content">你的内容</div>
</div>


然后这样写 CSS:

html, body {
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}

.full-screen-layout {
position: relative;
width: 100%;
height: 100vh;
/* 让容器本身不受安全区压缩 */
padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}

.bg-image {
position: absolute;
top: calc(0px - env(safe-area-inset-top));
left: calc(0px - env(safe-area-inset-left));
width: 100vw;
height: 100vh;
background: url('your-bg.jpg') center/cover no-repeat;
z-index: -1;
}

.content {
/* 内容区域自然留白,由父容器 padding 处理 */
flex: 1;
}


关键点在于 .bg-imagetopleft 要用负值把安全区“拉回来”,这样背景就能突破 safe area 向外扩展。而 .full-screen-layout 的 padding 确保内容不会被遮挡,这样布局和视觉就分开了,互不干扰。

这个方案在 iPhone 各型号、Android 刘海机上都测过,兼容性没问题。而且不用 JS,纯 CSS 解决,这样更清晰。
点赞 7
2026-02-09 15:36