关于safe-area-inset-x的处理方式总结

by

首先什么是safe-area-inset-*?直接翻译是:安全区域内嵌上/下/左/右,意思是网页显示内容需要内嵌的方向和长度。「caniuse和mdn介绍」。比较常见的是iPhoneX开始的“刘海”(notch)和某些安卓手机的非直角屏幕显示。如下图:

为什么这是一个需要解决的问题?

因为当页面中存在停靠在四个方向边缘的元素时,如果不预先考虑安全区域,就会造成内容的遮挡,影响功能使用和美观。比如顶部固定的功能栏、侧边悬浮的按钮、底部导航条等。

解决思路:

1. 通过设置viewport-fit:cover(铺满) | contain(包含)

<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> 

优点:简单直接,可满足可视和功能,保证不会被遮挡

缺点:无法保证美观度和一些细节,可能会造成不统一的背景颜色

2. 通过设置全局css,将根容器的pandding-x设置成对应的安全区域高度,

padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);

优点:简单,部分解决背景不统一问题

缺点:也无法保证美观和细节

3. 根据实际情况设置一组css,根据实际情况来处理

这里总结几种情况(只以top来举例):

1. 固定(fixed)和绝对(absolute)定位的顶部元素(通知条、顶部功能栏、左上角的返回按钮)

处理方式:top: env(safe-area-inset-top)

但这里需要注意,如果元素后面还有元素,比如header下面的content区域,由于header的top修改,会遮挡content,还需要修改相应的padding-top。(比如增加css类:below-fixed-top{padding-top:env(safe-area-inset-top)}

另一种情况,如果元素本身有top或者padding-top的设置,就需要外套一个元素来处理。这里引出了一个经验,布局框架内的根元素、第一级元素最好不要有任何top/padding-top/margin-top的设置。

2. 全局容器(高度100%,全屏弹出页)

处理方式:padding-top:env(safe-area-inset-top)

3. 普通容器

处理方式:给父容器设置padding-top:env(safe-area-inset-top),也可以通过增加伪元素(:before)来增加一个空的元素,这种方法可以设置显示内容。

不建议使用修改高度和margin的方式来处理,因为容器内通常还存在其他元素,可能会影响显示或布局,需要更多的适配。

特殊情况1:
比如在通常的fixed的左上角按钮,如果在其下部也有fixed的元素,则需要相应的下移。只能通过hardcode处理。