Appearance
安全区域适配 - mp-safe-area
提供了一种适配安全区域的解决方案,强烈建议在项目中使用,以确保风格一致性。
背景介绍
对于底部安全区域的适配,以前我们通常是这样做的:
css
.list {
padding-bottom: 0;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
这样做有什么问题呢?如果当容器本身就有下边距的时候,代码就要变成这样了:
css
.list {
padding-bottom: 120rpx;
padding-bottom: calc(120rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
}
OK,虽然有点烦,但问题也不大,毕竟对于底部安全区域,一直都是这样处理的,也就习惯了。
可相信你也一定遇到过顶部安全边距的场景,像这种(元素定位从导航栏底部开始):

还有这种(元素与右侧胶囊按钮位置居中对齐):

这两种布局在项目开发中非常常见,我们通常又是如何实现的呢?
由于没有现成的 CSS 变量,因此只能通过 JS 获取导航栏高度,以此作为容器的 padding-top
:
vue
<script setup>
import {device} from '@ifanrx/uni-mp'
const navbarHeight = device.getNavbarHeight()
</script>
<template>
<view class="page" :style="{paddingTop: navbarHeight + 'px'}">
我的位置在导航栏下面
</view>
</template>
第二种布局情况差不多,只需获取 wx.getMenuButtonBoundingClientRect().top
即可,这里不赘述。
问题就在于,明明是类似的问题,解法却不统一。因此,我们要寻求更好一点的解决方案。
来看看 uView 是怎么实现的:安全区适配,简而言之就是增加了两个组件:u-status-bar
和 u-safe-bottom
,想要设置安全距离的时候,挂一下这个组件即可,这样一来我们不需要手动设置 padding
,也无需关心如何取值。
所以我们参照 uView 做了一个组件:mp-safe-area
,它可以支持以下取值:
- safeTop
- safeBottom,
- navbar
- statusBar
- menuButtonTop
下面来介绍一下如何使用 mp-safe-area
。
基本用法
与 uView 不同,我们将不同类型的安全距离都放在同一个组件处理,只需传入不同的 type
属性即可。
底部安全距离
底部的安全距离适配是最常见的需求,因此我们将 safeBottom
设置为 type
的默认值。
在想要适配的地方挂一个 mp-safe-area
组件即可:
vue
<template>
<mp-nav-bar title="safe-bottom" />
<view class="page">
<view class="list">
<view v-for="index in 8" :key="index" class="card"></view>
</view>
<mp-safe-area />
</view>
</template>
顶部导航栏距离
对于前面那个例子,不需要再手动获取 navBarHeight
,同样只需要在上面挂一个 mp-safe-area
组件:
vue
<template>
<view class="page" :style="{ paddingTop: navbarHeight + 'px' }">
<view class="page">
<mp-safe-area type="navbar" />
我的位置在导航栏下面
</view>
</template>
右侧胶囊按钮垂直居中
对于需要与右侧胶囊按钮垂直居中的情况,也是一样:
vue
<template>
<view class="page">
<mp-safe-area type="menuButtonTop" />
<view>我和胶囊垂直居中</view>
</view>
</template>
安全距离适配容器(safe-layout)
TIP
通常情况下,mp-safe-layout
适用于大多数场景,特别是在涉及底部安全区域的情况下。但当 mp-safe-layout
无法满足特定需求时,可以考虑使用 mp-safe-area
。要注意区分两者的用途,正确使用合适的组件。