极速适配 iPhone X 秘籍
2017年9月苹果发布了 iPhone X 机型,对于它的“刘海儿”和底部 Home Indicator,QQ空间 H5 也在第一时间做了兼容适配。在适配过程中,我们尝试了这三种方案,如下。
解决方案1
客户端适配
客户端直接将 webview 的安全区域限制在除去安全区域的区域内。页面将展示在下图灰色 webview 内:
利弊分析
优点:H5 前端开发没有任何适配工作量。
缺点:页面会限制在客户端限制的 webview 区域内,没有满屏效果。
解决方案2
使用 media query
针对 iPhone X 机型在 html 结构的 meta 标签加入
<meta name="viewport" content="...,viewport-fit=cover" />
在 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 属性中加入:
<meta name="viewport" content="...,viewport-fit=cover" />
然后在需要的 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 的效果图。
对应代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<meta name="viewport" content="width=device-width, initial-scale=1,minimum-scale=1, maximum-scale=1, user-scalable=no,viewport-fit=cover" />
<style type="text/css">
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;
}
</style>
</head>
<body>
<div class="main">
<div class="top">————顶部————</div>
<div class="bottom">————底部————</div>
</div>
</body>
</html>
利弊分析
优点:符合标准的适配,灵活运用的话,H5 在不同 webview 下打开都可以有完美的展现。且考虑了未来机型的适配。
缺点:适配 iPhone X 时需要同时考虑其他 iOS 11 机型下会不会受到影响。
以上只分析竖屏 webview 下的情况,横屏 webview 可以自行通过模拟器进行研究。接下来介绍一下模拟器的使用。
iPhone X 模拟器 H5调试
介绍
加入适配代码后,在没 iPhone X 的情况下,可以通过 iPhone X 模拟器调试,像手机QQ / 手机空间里的 H5 页面,可以通过在模拟器上安装手机QQ / 手机空间app,然后调用 Safari 调试。
运行模拟器
系统要求:
1. Mac OS 10.12.6 以上
2. Xcode 9.0 以上
步骤:在 Xcode 打开一个空白项目,选择 iPhone X 模拟器,并点击运行按钮即可。
安装应用
在 Xcode 上直接编译客户端代码。或者让客户端开发编译一份模拟器版本的 .app 文件,将其拖进运行的模拟器屏幕,应用就成功安装了。
H5 调试
安装应用后,在应用里访问 H5 页面,然后打开 Safari(需要开启 Safari 的开发工具),在菜单中选择开发-Simulator-页面地址 ,就可以用 Safari 的检查器对其作调试了。(当有多个页面地址,将鼠标移至二级菜单的某一个页面地址时,模拟器页面屏幕会有蓝色遮罩出现时则是选中了本页面地址),有些时候 Safari 识别不到模拟器,只需退出 Safari ,点一下模拟器屏幕,再重新打开 Safari 一般就会出来了。
这种方法对于我们要调试线上 H5 的其他问题、要测试其他 iOS 设备找不到真机时同样适用。
最后
经过分析,使用官方提供的新属性是三种里面较佳的方案,不过在适配过程中应当整体考虑所有机型,webview 的类型及布局、还有横竖屏对contstant(safe-area-inset-X) / env(safe-area-inset-X) 值的影响。
本文转自腾讯ISUX (https://isux.tencent.com/articles/isux-h5-in-iphone.html)