iPhone X 适配方案
2017年9月苹果发布了 iPhone X 机型,对于它的“刘海儿”和底部 Home Indicator,QQ空间 H5 也在第一时间做了兼容适配。在适配过程中,我们尝试了这三种方案,如下。
解决方案1
客户端适配
客户端直接将 webview 的安全区域限制在除去安全区域的区域内。页面将展示在下图灰色 webview 内:
利弊分析
优点:H5 前端开发没有任何适配工作量。
缺点:页面会限制在客户端限制的 webview 区域内,没有满屏效果。
解决方案2
使用 media query
针对 iPhone X 机型在 html 结构的 meta 标签加入
在 css 中加入
@media only screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) {
...{ padding-top: 44px; }
...{ padding-bottom: 34px; }
}
适配效果
利弊分析
优点:对于 iPhone X 适配,最简单直接有效的方法,不会影响到其他 iOS 机型。
缺点:对于全屏 / 透顶标题栏 / 横屏情况都要用不同的 css 代码进行适配,不够灵活。另外,如果苹果下一年又发布了类似 iPhone X plus 这样的机型,适配工作就要重新来过。
解决方案3
使用苹果提供的新属性
苹果对于 iPhone X 上 H5 页面的适配,提供了特殊属性支持,包括 meta 标签的 viewport 属性值中加入 viewport-fit 和加入 constant(safe-area-inset-X) 和 env(safe-area-inset-X) ,这些属性是与 iOS 11 以上的所有 iPhone 机型 (不仅仅包括 iPhone X ) 都相关的,故以 iOS 版本为区别具体分析一下全屏下的 H5 页面:
1. 针对 iOS 11.0 以下系统:
将不识别 H5 页面 meta 标签下的 viewport-fit 及 constant(safe-area-inset-X) / env(safe-area-inset-X) 属性。
2. 针对 iOS 11.0 - iOS 11.1 的系统:
当设置了 viewport-fit=cover,H5 页面会覆盖页面安全区域全屏展示,但是这样会带来页面元素被“刘海儿”和底部 Home Indicator 遮挡的问题,所以苹果提供在 css 中设置 constant(safe-area-inset-X) 距离来规避遮挡问题。
这些在不同 webview 下会表现不同的值,我们留到后面分析。
另外,页面不加 viewport-fit=cover 默认 viewport-fit=contain/auto,也就是我们看到的页面不能覆盖安全区域的情况,此时 constant(safe-area-inset-X) 的值都为 0。
所以在 meta 标签的 viewpoint 中加 viewport-fit=cover 时 iOS 10 和 iOS 11 下constant(safe-area-inset-X) 值的表现是不一样的。
3. 针对 iOS 11.2 及 iOS 11.2 以上的系统:
constant() function 改成了 env(),其他与 iOS 11.2 以下表现一样 (详见第2点) 。另外,iOS 11.2 新增了 CSS function: min() 和 max() 。例如:
padding-left: max(12px, env(safe-area-inset-left));
在 env(safe-area-inset-left) 值因为 webview 变化时值也可以做出相应变化,取12px 和 env(safe-area-inset-left) 的较大值。
总结如下图:
在了解了以上情况后,大致可以知道如果要适配一个普通 H5 页面的顶部时,可以在 meta 标签的 viewport 属性中加入:
然后在需要的 class 里面加入:
...{
padding-top: 20px; /* iOS 10 */
padding-top: constant(safe-area-inset-top); /* iOS 11.0-iOS 11.1 */
padding-top: env(safe-area-inset-top); /*iOS 11.2 */
}
在 iOS 11 机型上,H5 加入 viewport-fit=cover 后,safeArea 的值是基于“如果布局接触了非安全区域才会赋值”。所以在不同情况下会有不同表现。如下表所示:
适配结果
这里展示了 iPhone 8 / iPhone X (iOS 11.2) 透顶状态栏 / 透顶标题栏 / 普通标题栏下打开适配 H5 的效果图。
对应代码:
test
html
{
background-color: #FFCD00;
}
html,body{
width: 100%;
height: 100%;
}
body, div{
margin: 0;
padding: 0;
}
.main{
font-size: 24px;
text-align: center;
width: 100%;
height: 100%;
padding-top: constant(safe-area-inset-top);
padding-top: env(safe-area-inset-top);
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
}