最近写⼩程序时,遇到了 iPhoneX 底部⼩⿊线与内容重叠的问题,实际上是iPhoneX安全区域的适配问题,了解清楚这个问题花了挺多时间的,也实操出了结果,忍不住来总结总结。
前⾔
在苹果 iPhoneX 、iPhone XR等设备上,可以看到物理Home键被取消,改为底部⼩⿊条替代home键功能。⼩程序和 h5 ⽹页需要针对这种情况进⾏适配,否则可能会遇到底部按钮或选项卡栏与底部⿊线重叠的情况,如下图。
1. 安全区域是什么意思?
想要解决内容与⼩⿊线重叠的问题,我们需要先了解清楚苹果对于安全区域的定义。
安全区域
安全区域指的是⼀个可视窗⼝范围,处于安全区域的内容不受圆⾓(corners)、齐刘海(sensor housing)、⼩⿊条(Home Indicator)的影响。
看看苹果官⽅给的这2张图就明⽩了,中间蓝⾊区域即为安全区域。也就是说,适配安全区域也就是让⼩程序或者H5的内容显⽰在蓝⾊区域部分。
同时安全区域是在IOS11之后并且是iPhoneX及以上机型才有的,所以需要适配的是这⼀类机型(为了⽅便,下⽂中统称这类需要适配的机型为iPhoneX),更⽼的机型则不需要考虑适配问题。
2. 在⼩程序上适配安全区域
三种⽅案:
使⽤已知底部⼩⿊条⾼度34px/68rpx来适配(不推荐)
使⽤官⽅API,getSystemInfo()中的safeArea对象进⾏适配(推荐)
苹果暗黑模式使⽤苹果官⽅推出的css函数env()、constant()适配(推荐)函数env()、constant()适配(推荐)的css函数env()、constant()适配(推荐)
⽅案⼀:使⽤已知底部⼩⿊条⾼度34px/68rpx来适配(不推荐)
这是⽐较⽼的⽅法,跟⽅案2、3⽐已经不推荐了,⼤家可以了解了解,着急可以直接看⽅案2和3。
从⽹上了解到,iPhone底部的⼩⿊条(Home Indicator)⾼度是34px,实际我也在真机确认了是34px,所以可以根据该值,设置底部按钮或选项卡的margin-bottom、padding-bottom、height等,或者添加⼀个div来占位⼩⿊条的位置。
这样做要有⼀个前提,需要判断当前机型是需要适配安全区域的机型。
问题:如何判断当前机型是需要适配安全区域
2种⽅案:
使⽤wx.getSystemInfoSync()的model属性判断
使⽤wx.getSystemInfoSync()中的screenHeight和safeArea对象的bottom属性判断
⽅法⼀:使⽤wx.getSystemInfoSync()的model属性判断
已知市⾯上已有的带安全区域的苹果设备包括iPhone X、iPhone XR、iPhone XS Max、iPhone 11、iPhone 11 Pro、iPhone 11 Pro Max,所以可以直接从
getSystemInfoSync()⽅法中拿到model属性进⾏判断。iPhone系列还未适配⼿机的model返回值为unknown(iphone),也可以提前做适配。
let IPHONE_X = /iphone x/i
let IPHONE_X_11 = /iphone 11/i
let IPHONE_UNKNOWN = /unknown\(iphone\)/i
//⽅法⼀:使⽤model判断是否是IPhoneX及其他包含安全区域的机型⼿机
const isIPhoneX = () => {
let model = wx.getSystemInfoSync().model
return (model.search(IPHONE_X) > -1 || model.search(IPHONE_X_11) > -1 ||
model.search(IPHONE_UNKNOWN) > -1)
}
//也可以使⽤正则表达式判断
const isIPhoneXRegex = () => {
let model = wx.getSystemInfoSync().model
return (/iphone\st(model)
|| (/st(model) && /unknown/.test(model))
|| /iphone\st(model))
}
⽅法⼆:使⽤wx.getSystemInfoSync()中的screenHeight和safeArea对象的bottom属性判断
这⾥使⽤screenHeight⽽不是windowHeight,因为bottom是以屏幕左上⾓为原点开始计算的,所以需要的是屏幕⾼度,对⽐screenHeight和bottom,如果相等则说明不需要适配,不相等则需要适配。
注意:如果使⽤开发者⼯具中的模拟器,screenHeight和bottom始终是相等的,需要⽤真机来测试。
//⽅法⼆:使⽤wx.getSystemInfoSync()中的screenHeight和safeArea的bottom判断
const isIPhoneX = () => {
let screenHeight = wx.getSystemInfoSync().screenHeight
let bottom = wx.getSystemInfoSync().safeArea.bottom
return screenHeight !== bottom
}
解决了如何判断设备是iPhoneX的问题,就可以写代码了。
<view class="bottom-button {{isIpX ? 'view-IPX' : ''}}">底部按钮</view>
⽅案⼆:使⽤官⽅API,getSystemInfo()中的safeArea对象进⾏适配(推荐)
使⽤wx. getSystemInfo()中的safeArea对象获取底部⼩⿊条的⾼度
step 1:使⽤上⾯讲的⽅法先判断是否是需要适配的iPhone机型
step 2:如果是需要适配的机型,使⽤safeArea中的bottom,得到安全区域底部纵坐标,然后使⽤screenHeight减去bottom就能得到⼩⿊条的⾼度。保存到localstorage⾥⾯,全局都可以使⽤。
⽅案三:使⽤苹果官⽅推出适配⽅案css函数env()、constant()来适配(推荐)
苹果官⽅推荐使⽤env(),constant()来适配,建议使⽤该⽅案,不需要管数值具体是多少。这2个⽅法是什么呢?
env()和constant(),是IOS11新增特性,Webkit的css函数,⽤于设定安全区域与边界的距离,有4个预定义变量:
safe-area-inset-left:安全区域距离左边边界的距离
safe-area-inset-right:安全区域距离右边边界的距离
safe-area-inset-top:安全区域距离顶部边界的距离
safe-area-inset-bottom :安全距离底部边界的距离
因为⽬标是需要对底部⼩⿊条做适配,所以只需要关注safe-area-inset-bottom这个值。
⽽env()和constant()函数有个必要的使⽤前提,当⽹页设置viewport-fit=cover的时候才⽣效,根据⼩程序的表现和我在实际真机测试时这两个函数⽣效,推测⼩程序⾥
的viewport-fit默认是cover。
有⼀点要注意,在IOS11.2系统以前,可以使⽤constant()函数,但是在IOS11.2系统以后,这个函数就被废弃了,被env()函数替代了。官⽅原话如下:The env() function shipped in iOS 11 with the name constant(). Beginning with Safari Technology Preview 41 and the iOS 11.2 beta, constant() has been removed and replaced with env(). You can use the CSS fallback mechanism to support both versions, if necessary, but should prefer env() going forward.
所以我们在做屏幕适配时,需要这样写:
padding-bottom: constant(safe-area-inset-bottom); /*兼容 IOS<11.2*/
padding-bottom: env(safe-area-inset-bottom); /*兼容 IOS>11.2*/
注意:env()和constant()需要同时存在,⽽且顺序不能换。
3. 在H5上适配安全区域
在H5上适配安全区域就⽅便多了,采⽤viewport+env+constant⽅案。
viewport-fit 默认有3个值:
contain:可视窗⼝完全包含⽹页内容(左图)
cover:⽹页内容完全覆盖可视窗⼝(右图)
auto:默认值,此值不影响初始布局视图端⼝,并且整个web页⾯都是可查看的。
contain和cover具体区别如下图:
⽽我们需要将viewport设置为cover,env和constant才能⽣效。设置代码如下:
<meta name="viewport" content="width=device-width,initial-scale=1.0,viewport-fit=cover">
同时设置env和constant代码,同样env()和constant()需要同时存在,⽽且顺序不能换。
/* 可以通过增加padding-bottom来适配 */
padding-bottom: constant(safe-area-inset-bottom); /*兼容 IOS<11.2*/
padding-bottom: env(safe-area-inset-bottom); /*兼容 IOS>11.2*/
/* 可以通过margin-bottom来适配 */
margin-bottom: constant(safe-area-inset-bottom);
margin-bottom: env(safe-area-inset-bottom);
/* 或者改变⾼度*/
height: calc(55px + constant(safe-area-inset-bottom));
height: calc(55px + env(safe-area-inset-bottom));
也可以在底部添加⼀个空⽩的div颜⾊块来做适配。
还有⼀种是使⽤ @supports 隔离兼容样式
可以使⽤ @supports 来隔离兼容样式,当浏览器⽀持bottom: constant(safe-area-inset-bottom)或者bottom: env(safe-area-inset-bottom)的时候,bottom-button类就会新增margin-bottom的样式
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
.bottom-button {
margin-bottom: constant(safe-area-inset-bottom);
margin-bottom: env(safe-area-inset-bottom);
}
}
以上就是我对iPhoneX安全区域(Safe Area)底部⼩⿊条在⼩程序和H5适配的总结。
如果对你有帮助的话,点赞、评论、赞赏都是对我的⿎励,也是⽀持我写下去的动⼒,谢谢!
参考⽂章:
到此这篇关于iPhoneX安全区域(Safe Area)底部⼩⿊条在⼩程序和H5的屏幕适配的⽂章就介绍到这了,更多相关iPhoneX底部H5的屏幕适配内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章,希望⼤家以后多多⽀持!
发布评论