在H5开发过程中遇到一个兼容性问题。iphone手机的虚拟home键会对屏幕底部的内容造成遮挡。要处理此问题,需要清楚安全区域这个概念。
安全区域
根据刘海和虚拟Home键,Apple为其设备提供了屏幕安全区域的视觉规范
- 竖屏:竖屏的时候,顶部往下44pt,底部往上34pt,中间部分是安全区域。
- 横屏:而横屏时候则相对复杂一些,因为虚拟指示条通常情况下都是出现在屏幕底部,所以不仅屏幕左右会留出 44pt 的空白位置,屏幕底部也会留出 21pt 的位置。
配置方案
在ios11中我们可以采用view-fit=‘cover’ + safe-area-inset-* 来解决此兼容问题。
关于viewport-fit
viewport-fit 可以设置可视视窗的大小,它有三个属性值:
- Auto:默认值。这个值不影响初始布局视窗,整个 Web 页面是可视的,与Contain表现一致。
- Contain:最初的布局视窗和视觉布局视窗被设置为最大的矩形(左图)。
- Cover:初始布局视窗和视觉布局视窗被设置为设备物理屏幕的限定矩形(右图)。
关于safe-area-inset-*
各种 iPhone x 都是不规则形状,我们如何控制页面元素到安全区域呢?Apple 把安全区域的位置通过 css 属性提供给了开发者,它们可以通过CSS的constant( )函数来完成:
- constant(safe-area-inset-top):在Viewport顶部的安全区域内设置量(CSS像素)
- constant(safe-area-inset-bottom):在Viewport底部的安全区域内设置量(CSS像素)
- constant(safe-area-inset-left):在Viewport左边的安全区域内设置量(CSS像素)
- constant(safe-area-inset-right):在Viewport右边的安全区域内设置量(CSS像素)
简单来说我们可以通过 constant( ) 可以获取到非安全边距,再结合 padding 或 margin 来控制页面元素避开非安全区域。 Webkit 在 iOS11 中新增 CSS Functions: env( ) 替代 constant( ),文档中推荐使用 env( ),而 constant( ) 从 Safari Techology Preview 41 和 iOS11.2 Beta 开始会被弃用。在不支持 env( ) 的浏览器中,会自动忽略这一样式规则,不影响网页正常的渲染。为了达到最大兼容目的,我们可以 constant( ) 和 env( ) 同时使用。
.footerClass {padding-bottom: constant(safe-area-inset-bottom); /* iOS 11.0 */padding-bottom: env(safe-area-inset-bottom); /* iOS 11.2 */
}
解决
1.设置网页在可是区域的布局方式
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, minimum-scale=1, maximum-scale=1.0, user-scalable=0">
2.让主题内容控制在安全区域内
body {padding-top: env(safe-area-inset-top);padding-right: env(safe-area-inset-right);padding-bottom: 50px; /* 兼容不支持 env( ) 的设备 */padding-bottom: calc(env(safe-area-inset-bottom) + 50px); /* 在 iphone x + 中本句才会生效 */padding-left: env(safe-area-inset-left);
}
参考:https://juejin.cn/post/6963941148163473445