艺灵设计

全部文章
×

移动端页面适配之iPhoneX的安全区域

作者:艺灵设计 - 来源:http://www.yilingsj.com - 发布时间:2020-07-26 23:32:19 - 阅: - 评:0 - 积分:0

摘要:说起有关iPhoneX的适配问题,网上资源一搜一大把,而这些资源文章中的代码中或多或少会出现viewport-fit=cover和safe-area-inset-bottom的影子。之前我对这块的认知也是比较浅显的,毕竟不是壕没有壕机。前段时间在工作中又遇到了此类问题,当时采用远程聊天的方式来解决。今天有幸体现了一把iPhoneX真机,觉得有必要记录一笔......

感谢@文杰提供iPhoneX壕机供我测试代码。

一、为什么要适配iPhoneX的安全区域?

估计有很多不知情的看官会跟我有同样的疑问,为啥要适配iPhoneX的安全区域?如果不适配会怎样?还是来张iPhoneX的真机靓照吧。如图:iPhoneX手机的靓照.pngiPhoneX手机的靓照

不用怀疑,这就是一部iPhoneX手机,只不过现在横放着了。好像现在看不出来与普通手机有什么区别,别急,我们再来看一下加上注释后的效果。如图:iPhoneX手机中的安全区域.pngiPhoneX手机中的安全区域

图中画圈的地方就是今天的主角儿!可以看到,右侧的“刘海”和正下方的“短横条”都会挡住页面区域,仅管被遮挡的区域很小。由于上图都是颜色区块儿,看得不明显,我们再来张正常的场景图。如图:iPhoneX手机下方的短横条挡住了底部导航.pngiPhoneX手机下方的短横条挡住了底部导航

二、如何适配?

相信看到这篇文章的看官或多或少已经踩过此坑,方案无外乎viewport-fit=coversafe-area-inset-*,当然也有用空盒子写死高度的方案。运气好的话,Ctrl+C、Ctrl+V到项目中就解决了问题。运气不好的话,可能还要调试个把小时才能解决问题。出现此种现象的原因主要跟我们写的css有关!下面,艺灵就用三个场景来分情况讨论安全区域在页面中的影响及如何解决。废话不多说,进入主题。

2.1、场景一:普通页面,无底部导航栏

这种页面最常见了,比如:在手机上的浏览器中打开x度搜索任意内容,也可以打开其他网站,只要底部没有固定的导航栏就行。

个人认为:在页面上滑浏览过程中,这个不算影响用户体验。但是,当页面滑到底部的时候,底部的短横条就比较碍眼了,此时我们就需要做安全区域的适配。关于底部的适配代码是safe-area-inset-bottom,这玩意儿加在哪里呢?

由于每个页面都有body,所以理想状态是给body设置此值。当然也可以给body内的节点添加,但这并不是极佳方案。

  1. <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"> <!-- 添加一个meta头 -->

这一步必须要有,否则css代码无效!前面半段是为了让页面适配移动端,后面黄色高亮的viewport-fit=cover才是重点!网上对其解释为:“网页内容完全覆盖可视窗口”。

  1. body {
  2.   ...... /* 你原本的样式 */
  3.   padding-bottom: constant(safe-area-inset-bottom); /* 适配安全区域 iOS < 11.2 */
  4.   padding-bottom: env(safe-area-inset-bottom); /* 适配安全区域 iOS >= 11.2 */
  5. }

下面提供两个对比的二维码,有兴趣的看官直接用iPhoneX手机扫码体验下吧。

2.2、场景二:普通页面+底部导航栏(fixed)

相对于场景一,有底部导航栏的页面常见于类商城的网站。若写代码的作者使用了position:fixed来让底部导航栏固定在页面底部,那问题就稍微麻烦了一些。

既然页尾使用了fixed,那么必然会有一个空的占位的盒子来撑起页面的高度,否则页面在滚动到底部时,悬浮的底部导航栏会挡住一部分内容。当然,也可以用paddingmargin的方案来撑起页面。还可以用固定高度的骚操作实现,反正方法不唯一。

对于当前的场景而言,如果只给悬浮的底部导航栏添加safe-area-inset-bottom代码的话,并不能完全解决问题,因为那个占位的空盒子高度没有导航栏的高度高。当页面滚动到非底部时,还有可能会出现比较尴尬的事情。如图:导航栏在半空中?这也太尴尬了吧.png比较尴尬的情况出现了解释一下,出现上图的原因是使用了margin-bottom而非padding-bottom所以,这个时候场景一的代码仍然是极佳方案!

  1. <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"> <!-- 添加一个meta头 -->
  1. body {
  2.   ...... /* 你原本的样式 */
  3.   padding-bottom: constant(safe-area-inset-bottom); /* 适配安全区域 iOS < 11.2 */
  4.   padding-bottom: env(safe-area-inset-bottom); /* 适配安全区域 iOS >= 11.2 */
  5. }
  6. .footer_fixed { /* 悬浮导航的类名(复制后请改成你自己的) */
  7.   ...... /* 你原本的样式 */
  8.   padding-bottom: constant(safe-area-inset-bottom); /* 适配安全区域 iOS < 11.2 */
  9.   padding-bottom: env(safe-area-inset-bottom); /* 适配安全区域 iOS >= 11.2 */
  10. }

这样做的好处就是:即使页面中的悬浮底部导航栏因需求砍掉了,原来的页面也能适配iPhoneX的安全区域。而且是所有页面哦,并不局限于只有底部导航栏的页面哈。

有兴趣的看官直接用iPhoneX手机扫码体验下吧。

2.3、场景三:flex布局+底部导航栏

此场景跟场景二在最终展现效果上没太大的区别,唯一的区别就是布局方式不同!而flex布局的优势也很明显,精简的代码实现了多端的适配,也是现在流行的布局方案。

如果看官在此种布局方案上适配iPhoneX的安全区域,极有可能出现代 码 无 效 的情况!

  1. <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"> <!-- 添加一个meta头 -->
  2. <div class="page">
  3.   <div class="page-header">头部</div>
  4.   <div class="page-content">
  5.     页面主体内容区<br>这就是传说中的flex布局,头部和尾部“固定”,中间内容区自适应高度
  6.   </div>
  7.   <div class="page-footer">页尾</div>
  8. </div>
  1. body {
  2.   ...... /* 你原本的样式 */
  3.   height: 100vh;
  4.   box-sizing: border-box; /* 非常重要! */
  5.   padding-bottom: constant(safe-area-inset-bottom); /* 适配安全区域 iOS < 11.2 */
  6.   padding-bottom: env(safe-area-inset-bottom); /* 适配安全区域 iOS >= 11.2 */
  7. }
  8. .page {
  9.   display: flex;
  10.   flex-direction: column;
  11.   height: 100%; /* 若没有上面的body代码,此处可以用vh单位,适配代码同样可以写在此类名下 */
  12. }
  13. .page-header {
  14.   line-height: 3;
  15.   background-color: #8b8b8b;
  16. }
  17. .page-content {
  18.   flex: 1;
  19.   overflow-y: auto;
  20.   background-color: #6fb9eb;
  21. }
  22. .page-footer {
  23.   line-height: 1.2;
  24.   background-color: #c6ff7d;
  25. }

现在,这个页面也可以适配iPhoneX的安全区域了。有兴趣的看官直接用iPhoneX手机扫码体验下吧。

三、当代码中本身有padding属性时要咋整?

啥意思呢?看下面的代码吧。

  1. #app {
  2.   padding-bottom: 20px;
  3. }

当上面的#app样式中已经设置了padding-bottom时,这个时候显示不能直接使用适配安全的代码,需要借助calc来实现兼容处理。

  1. #app {
  2.   padding-bottom: calc(20px + constant(safe-area-inset-bottom)); /* 适配安全区域 iOS < 11.2 */
  3.   padding-bottom: calc(20px + env(safe-area-inset-bottom)); /* 适配安全区域 iOS >= 11.2 */
  4. }

现在,我们就实现了兼容原来的代码了。

上面提供了6张二维码,分别展示了3种布局下的效果。在文章末尾,又提供了一种复杂情况,看官在工作中可以根据实际情况来选择使用哪种解决方案。

三、最后

再次感谢@文杰同学,也感谢以下资料:
移动端上的设计和适配
h5 在全屏iphonex中的适配

转载声明:
  若亲想转载本文到其它平台,请务必保留本文出处!
本文链接:http://www.yilingsj.com/xwzj/2020-07-26/iPhoneX-safe-area-inset-bottom.html

若亲不想直保留地址,含蓄保留也行。艺灵不想再看到有人拿我的技术文章到他的地盘或者是其它平台做教(装)程(B)而不留下我的痕迹。文章你可以随便转载,随便修改,但请尊重艺灵的劳动成果!谢谢理解。

亲,扫个码支持一下艺灵呗~
如果您觉得本文的内容对您有所帮助,您可以用支付宝打赏下艺灵哦!

Tag: web 前端开发 移动端开发 页面适配 iPhoneX适配 viewport-fit safe-area-inset-bottom flex布局

上一篇: @vue/cli3+typescript项目实战之给无限级嵌套的导航添加激活样式(上)   下一篇: 返回列表

评论区