适配移动端页面顶部安全区域
适配移动端顶部安全区域。
- 使用vant 导航组件,开启刘海屏适配safe-area-inset-top 为true
<van-nav-bar
:title="props.title"
left-arrow
@click-left="goBack"
:safe-area-inset-top="true"
class="navbar"
>
1
2
3
4
5
6
7
2
3
4
5
6
7
2,页面给一个顶部的高度padding,一般是导航栏高度44 + 刘海高度。
.pt-nav {
//使用vant导航高度变量 + 环境变量safe-area-inset-top iOS 使用 constant 安卓使用 env
//env() 跟 constant() 需要同时存在,而且顺序不能换。
padding-top: calc(var(--van-nav-bar-height) + constant(safe-area-inset-top));
padding-top: calc(var(--van-nav-bar-height) + env(safe-area-inset-top));
box-sizing: border-box;
}
1
2
3
4
5
6
7
2
3
4
5
6
7
//还需要在index.html设置viewport,上面属性才能取到值
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover" />
1
2
3
2
3
# 注意:
safe-area-inset-top 属性在个别的安卓手机上面是取不到高度值的,所以需要特殊适配,失效的情况:
- 给一个默认的 padding-top 40px 防止失效。 (测试下来,还是会有手机失效,比如部分oppo手机)
padding-top: 40px;
padding-top: constant(safe-area-inset-top);
padding-top: env(safe-area-inset-top);
1
2
3
2
3
- 使用js方法获取高度 首先我们向页面中插入一个看不见的 div,将 div 的高度设置为安全距离的高度,然后再通过 js 获取其高度,若高度为 0,则说明没有生效。 那么在已经设置了安全区域属性的地方,都需要额外执行下 supportSafeArea()方法:
let status = 0; // 0:还没数据,-1:不支持,1:支持
/**
* 判断当前设置是否支持constant(safe-area-inset-top)或env(safe-area-inset-top);
* 部分Android设备,可以认识safa-area-inset-top,但会将其识别为0
* @returns {boolean} 当前设备是否支持安全距离
*/
const supportSafeArea = (): boolean => {
if (status !== 0) {
// 缓存数据,只向 body 插入一次 dom 即可
return status === 1;
}
const div = document.createElement('div');
const id = 'test-check-safe-area';
const styles = [
'position: fixed',
'z-index: -1',
'height: constant(safe-area-inset-top)',
'height: env(safe-area-inset-top)',
];
div.style.cssText = styles.join(';');
div.id = id;
document.body.appendChild(div);
const areaDiv = document.getElementById(id);
if (areaDiv) {
status = areaDiv.offsetHeight > 0 ? 1 : -1; // 该 div 的高度是否为 0
areaDiv.parentNode?.removeChild(areaDiv);
}
return status === 1;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 注意2
除了safe-area-inset-top。
还有:
safe-area-inset-left:安全区域距离左边边界的距离
safe-area-inset-right:安全区域距离右边边界的距离
safe-area-inset-top:安全区域距离顶部边界的距离
safe-area-inset-bottom:安全区域距离底部边界的距离
使用方法参照上面即刻。
上次更新: 2024/08/07, 18:05:11