iPhone X底部安全区域适配为什么设置了padding还是被遮挡?

爱学习的柯佳 阅读 56

在做Vue项目时,底部导航栏在iPhone X上总被Home Indicator遮挡,虽然设置了padding-bottom: constant(...),但实际显示还是顶到屏幕边缘。

我按教程写了一个适配组件:


<template>
  <div class="safe-area" :style="safeAreaStyle">
    
  </div>
</template>

<script>
export default {
  data() {
    return {
      safeAreaStyle: {
        paddingBottom: window.safeAreaInsets?.bottom + 'px'
      }
    }
  }
}
</script>

但测试时发现:真机iOS15.2上正常,iOS13.7却报错window.safeAreaInsets is undefined。难道只能用meta viewport标签和CSS变量一起用吗?实在搞不懂怎么兼容了

我来解答 赞 11 收藏
二维码
手机扫码查看
1 条解答
♫柚溪
♫柚溪 Lv1
这个问题主要是因为不同iOS版本对安全区域的处理方式不一样,iOS13及以下并没有提供 window.safeAreaInsets 这个API,所以会报undefined错误。稳妥的做法是结合CSS环境变量和JavaScript动态检测来做适配。

首先在HTML的meta标签里加上viewport-fit=cover,这一步很关键,不然CSS的安全区域变量不会生效:
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">


然后修改你的样式代码,用env(safe-area-inset-bottom)来设置padding,这是标准的安全区域变量:
.safe-area {
padding-bottom: env(safe-area-inset-bottom, 0px);
}


至于JS部分,你需要做版本兼容判断。直接访问 window.safeAreaInsets 可能会报错,建议这样写:
const safeAreaInsets = window.safeAreaInsets || {};
const bottomInset = parseFloat(safeAreaInsets.bottom) || 0;

export default {
data() {
return {
safeAreaStyle: {
paddingBottom: ${bottomInset}px
}
}
}
}


这里用了parseFloat来防止注入攻击,确保取到的是数值。另外要注意,即使设置了这些,有些老旧webview可能还是不支持,最好让用户升级系统或者使用最新的浏览器。

最后提醒一下,测试的时候别只看模拟器,真机的表现可能会有差异,尤其是第三方app内置的webview环境。我之前就被坑过好几次,老版本的webview各种奇葩问题,建议做好降级方案。
点赞 3
2026-02-15 17:00