iPhone X适配

北京时间 9 月 12 日凌晨,苹果在乔布斯剧院发布了 iPhone X。iPhone X 正面的全面屏上方有一条刘海,对于如何适配 iPhone X,苹果的 Human Interface Guidelines 文档已经给出详细的说明。
作为Web端开发者,我们关心如何在苹果给出的适配方案基础上,在我们的App端与H5端表现良好。

本文将剖析我们在App/H5适端配iPhone X的方案。

  • 未做 iPhone X 适配之前的页面

    存在的问题:

    • 吸底设置了 bottom: 0 ,但页面的底部依然有空隙,且空隙的内容可发生点击等交互;同样的,弹层设置高度 100%,页面底部也有空隙。

    原因分析:

    • iPhone X 非矩形屏幕,viewport 边界框 与 设备显示区域 不一致。分期乐APP的 webView 默认情况下,viewport 是设备显示区域内的最大矩形框,上下两个圆角矩形的区域成为了 viewport 之外的显示空隙。这些区域由 UA 自动选择显示其认为的合适的内容。


      解决办法:

    通过设置 viewport-fit 来调整 viewport

    1
    2
    3
    4
    5
    auto:这个值不影响初始布局视窗,整个Web页面是可视的。在视窗之外的UA绘制的是未定义的,它可能是画布的背景色,或者是UA认为合适的其他东西
    contain:最初的布局视窗和视觉布局视窗被设置为最大的矩形。在Viewport之外的UA绘制的是未定义的,它可能是画布的背景色,或者UA认为合适的其他东西
    cover:初始布局视窗和视觉布局视窗被设置为设备物理屏幕的限定矩形

    这儿,我们设置 viewport-fi= cover ,把初始的 viewport 设定为设备物理屏幕受限的矩形:

    1
    <meta name="viewport" content="viewport-fit=cover,width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">

    黄色区域于设备显示区域,蓝色+黄色的矩形为 viewport-fit: cover之后的 viewport ,四个蓝色区域为超出可显示区域之外的区域。

    设置之后的页面:

    设置之后,吸底和弹窗似乎满足我们的要求的了。但是又出现了新的问题,iPhone X 的底部有系统手势操作区域,吸底与该区域重合是不合理的;吸底的左右边缘文字被圆角矩形遮盖。因此,我们需要把吸底上移,让其离开手势操作区域,又不显示其他背景内容。

    这时,我们可以借助苹果提供的 CSS constant() 来进行下一步操作:

    1
    2
    3
    4
    5
    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像素)
    // safe-area-inset 由系统自动提供

    webkit官方最新推荐使用 env() 来代替 constant() ,所以,我们给吸底的 div.nav-bottom-wrap 添加:

    1
    2
    3
    4
    .nav-bottom-wrap{
    padding-bottom: constant(safe-area-inset-bottom);
    padding-bottom: env(safe-area-inset-bottom);
    }

横屏:
从Xcode上的iphoneX模拟器效果可以看出,env()与constant()在横屏模式下生效,但页面在横屏上体验不佳,存在以下几点问题:

① 吸底伴随着页面滑动,吸底会存在偶然下沉或消失的现象。无法判断是模拟器原因还是其他原因(需要在IOS11真机/iPhone X上进行测试)。
② 针对右侧这种 规则/返回顶部,需要设置右侧的安全距离(旋转后安全距离会按照当前方向的上下左右重新计算,所以可以直接使用safe-area-inset-right)),防止出现图中情况。

1
2
3
4
.floating{
right: env(safe-area-inset-right);
right: constant(safe-area-inset-right);
}

但是它的右安全区域在这个位置,大概效果是这样子。会相对于页面的右边向左偏移一点。

针对iphoneX在微信/UC等第三方浏览器中横屏表现,无法进行测试。

最后呈现的页面:

其他说明:

因为Xcode上iphoneX
横屏全屏情况还未测试,但解决方式应该类似。