再聊移动端页面的适配

再聊移动端页面的适配

前端圈真乱,这话一点不假。但乱也乱的好处,乱则生变,有变化才有进步。今天仍是老调重谈,聊聊移动端页面的适配。由于对于一枚前端而言,每天和页面打交道(H5页面),那么布局的活老是少不了,这也将面临不一样终端的适配问题。不知道你是否和我同样,页面布局老是或多或少会有一些蛋疼的事情发生。若是是的话,建议你花点时间阅读完下面我扯蛋的东东。css

Flexible承载的使命

Flexible到今天也有几年的历史了,解救了不少同窗针对于H5页面布局的适配问题。而这套方案也相对而言是一个较为成熟的方案。简单的回忆一下,当初为了能让页面更好的适配各类不一样的终端,经过Hack手段来根据设备的dpr值相应改变<meta>标签中viewport的值:html

img

从而让页面达么缩放的效果,也变相的实现页面的适配功能。而其主要的思想有三点:前端

  • 根据dpr的值来修改viewport实现1px的线
  • 根据dpr的值来修改htmlfont-size,从而使用rem实现等比缩放
  • 使用Hack手段用rem模拟vw特性

有关于Flexible方案实现适配,在2015年双十一以后作过这方面的技术文档分享,感兴趣的同窗能够移步阅读《使用Flexible实现手淘H5页面的终端适配》一文。虽然Flexible解决了适配终端不少问题,但它并非万能的,也不是最优秀的,他仍是存在一些问题的,好比iframe的引用,有时候就把咱们本身给埋进去了。针对其中的一些不足之处,有些同窗对其进行过相关的改造,在网上搜索能找到相关的方案。css3

那么时代在变化,前端技术在不断的变化,试问:Flexible仍是最佳方案?Flexible还有存在的必要吗? 最近一直在探讨这方面,这里先告诉你们Flexible已经完成了他自身的历史使命,咱们能够放下Flexible,拥抱新的变化。接下来的内容,我将分享一下我最近本身探讨的新的适配方案,或许不少团队同窗已经开始使用了,若是有不对之处,但愿能获得大婶们的指正;若是您有更好的方案,但愿能一块儿分享一块儿探讨。浏览器

先上菜,再唠嗑

先上个二维码:svg

img

你可使用手淘App、优酷APP、各终端自带的浏览器、UC浏览器、QQ浏览器、Safari浏览器和Chrome浏览器扫描上面的二维码,您看到相应的效果:函数

img

iPhone系列效果工具

img

部分Android效果布局

注:若是扫上面的二维码没有任何效果,你能够点击这里,打开在线页面,从新生成你的设备能识别的二维码号 。post

上面的Demo,测试了Top30的机型。目前未获得支持的:

img

Top30机型中不在列表中的,将看到的效果如上图所示。至于敢不敢用,这就得看亲了。必竟第一个吃螃蟹的人是须要必定的勇气!(^_^)

适配方案

前面给你们介绍了这个方案目前获得的支持状况以及效果。也扯了很多废话,接下来进入正题吧。

在移动端布局,咱们须要面对两个最为重要的问题:

  • 各终端下的适配问题
  • Retina屏的细节处理

不一样的终端,咱们面对的屏幕分辨率、DPR、1px2x图等一系列的问题。那么这个布局方案也是针对性的解决这些问题,只不过解决这些问题再也不是使用Hack手段来处理,而是直接使用原生的CSS技术来处理的。

适配终端

首要解决的是适配终端。回想一下,之前的Flexible方案是经过JavaScript来模拟vw的特性,那么到今天为止,vw已经获得了众多浏览器的支持,也就是说,能够直接考虑将vw单位运用于咱们的适配布局中。

众所周知,vw是基于Viewport视窗的长度单位,这里的视窗(Viewport)指的就是浏览器可视化的区域,而这个可视区域是window.innerWidth/window.innerHeight的大小。用下图简单的来示意一下:

img

由于Viewport涉及到的知识点不少,要介绍清楚这方面的知识,都须要几篇文章来进行阐述。@PPK大神有两篇文章详细介绍了这方面的知识。中文能够移步这里进行阅读。

在CSS Values and Units Module Level 3中和Viewport相关的单位有四个,分别为vwvhvminvmax

  • vw:是Viewport's width的简写,1vw等于window.innerWidth1%
  • vh:和vw相似,是Viewport's height的简写,1vh等于window.innerHeihgt1%
  • vminvmin的值是当前vwvh中较小的值
  • vmaxvmax的值是当前vwvh中较大的值

vminvmax是根据Viewport中长度偏大的那个维度值计算出来的,若是window.innerHeight > window.innerWidthvmin取百分之一的window.innerWidthvmax取百分之一的window.innerHeight计算。

仍是用一张图来示意吧,一图胜于千言万语:

img

因此在这个方案中大胆的使用vw来替代之前Flexible中的rem缩放方案。先来回归到咱们的实际业务中来。目前出视觉设计稿,咱们都是使用750px宽度的,从上面的原理来看,那么100vw = 750px,即1vw = 7.5px。那么咱们能够根据设计图上的px值直接转换成对应的vw值。看到这里,不少同窗开始感到崩溃,又要计算,能不能简便一点,能不能再简单一点,实际上是能够的,咱们可使用PostCSS的插件postcss-px-to-viewport,让咱们能够直接在代码中写px,好比:

img

PostCSS编译以后就是咱们所须要的带vw代码:

img

在实际使用的时候,你能够对该插件进行相关的参数配置:

img

假设你的设计稿不是750px而是1125px,那么你就能够修改vewportWidth的值。有关于该插件的详细介绍,能够阅读其官方使用文档。

上面解决了pxvw的转换计算。那么在哪些地方可使用vw来适配咱们的页面。根据相关的测试:

  • 容器适配,可使用vw
  • 文本的适配,可使用vw
  • 大于1px的边框、圆角、阴影均可以使用vw
  • 内距和外距,可使用vw

另外有一个细节须要特别的提出,好比咱们有一个这样的设计:

img

若是咱们直接使用:

img

最终的效果会形成[w-187-246]容器的高度小于[w-188-246]容器的高度。这个时候咱们就须要考虑到容器的长宽比缩放。这方面的方案不少,但我仍是推荐工具化来处理,这里推荐@一丝 姐姐写的一个PostCSS插件postcss-aspect-ratio-mini。这个插件使用很简单,不须要作任何的配置,你只须要本地安装一下就OK。使用的时候以下:

img

编译出来:

img

这样就能够完美的实现长宽比的效果。有关于这方面的原理在这里不作过多阐述,感兴趣的话能够阅读早前整理的文章:

  • CSS实现长宽比的几种方案
  • 容器长宽比
  • Web中如何实现纵横比
  • 实现精准的流体排版原理

目前采用PostCSS插件只是一个过渡阶段,在未来咱们能够直接在CSS中使用aspect-ratio属性来实现长宽比。

解决1px方案

前面提到过,对于1px是不建议将其转换成对应的vw单位的,但在Retina下,咱们始终是须要面对如何解决1px的问题。在《再谈Retina下1px的解决方案》文章中提供了多种解决1px的方案。在这里的话,我的推荐另一种解决1px的方案。依旧是使用PostCSS插件,解决1px可使用postcss-write-svg。

使用postcss-write-svg你能够经过border-image或者background-image两种方式来处理。好比:

img

这样PostCSS会自动帮你把CSS编译出来:

img

使用PostCSS的插件是否是比咱们修改图片要来得简单与方便。

上面演示的是使用border-image方式,除此以外还可使用background-image来实现。好比:

img

编译出来就是:

img

这个方案简单易用,是我所须要的。目前测试下来,基本能达到我所须要的需求。但有一点千万别忘了,记得在<head>中添加:

img

上面阐述的是这个适配方案中所用到的技术点,简单的总结一下:

  • 使用vw来实现页面的适配,而且经过PostCSS的插件postcss-px-to-viewport把px转换成vw。这样的好处是,咱们在撸码的时候,不须要进行任何的计算,你只须要根据设计图写px单位
  • 为了更好的实现长宽比,特别是针对于imgvedioiframe元素,经过PostCSS插件postcss-aspect-ratio-mini来实现,在实际使用中,只须要把对应的宽和高写进去便可
  • 为了解决1px的问题,使用PostCSS插件postcss-write-svg,自动生成border-image或者background-image的图片

这里使用了多个PostCSS的插件,其实如今有不少优秀的PostCSS插件能帮助咱们解决不少问题。哪果你从未接触过有关于PostCSS相关的知识,建议你能够花点时间去学习一下,在W3cplus提供了一些有关于PostCSS相关的文章。若是你想系统的学习PostCSS相关的知识,推荐你购买《深刻PostCSS Web设计》一书:

img

降级处理

最开始提到过,到目前为止,T30的机型中还有几款机型是不支持vw的适配方案。那么若是业务须要,应该怎么处理呢?有两种方式能够进行降级处理:

  • CSS Houdini:经过CSS Houdini针对vw作处理,调用CSS Typed OM Level1 提供的CSSUnitValue API。
  • CSS Polyfill:经过相应的Polyfill作相应的处理,目前针对于vw单位的Polyfill主要有:vminpoly、Viewport Units Buggyfill、vunits.js和Modernizr。我的推荐采用Viewport Units Buggyfill

Viewport不足之处

采用vw来作适配处理并非只有好处没有任何缺点。有一些细节之处仍是存在必定的缺陷的。好比当容器使用vw单位,margin采用px单位时,很容易形成总体宽度超过100vw,从而影响布局效果。对于相似这样的现象,咱们能够采用相关的技术进行规避。好比将margin换成padding,而且配合box-sizing。只不过这不是最佳方案,随着未来浏览器或者应用自身的Webview对calc()函数的支持以后,碰到vwpx混合使用的时候,能够结合calc()函数一块儿使用,这样就能够完美的解决。

另一点,px转换成vw单位,多少还会存在必定的像素差,毕竟不少时候没法彻底整除。

到目前为止,我发现的两个不足之处。或许在后面的使用当中,还会碰到一些其余不为人之的坑。事实也是如此,无论任何方案,踩得坑越多,该方案也愈来愈强大。但愿喜欢这个适配方案的同窗和我一块儿踩坑,让其更为完善。

如何判断本身的应用是否支持

虽然该文的示例,进行了多方面的测试。但不少同窗仍是会担心本身的APP应用是否支持该方案,而不敢大胆尝试或者使用。其实没必要要这么担忧,你能够拿本身的设备,或者应用扫描下面的二维码:

img

当页面跑完测试以后,找到对应的Values and Units列表项:

img

若是vw栏是绿色表明你的设备或应用支持该方案;反之则不支持。另外你也能够常常关注css3test相关的更新,后面将会根据相关的规范更新测试代码,让你能快速掌握哪些属性能够大胆使用。

总结

H5页面的适配方案老是使人蛋疼的,事实上页面的布局老是使人蛋疼的。但技术是不断革新的,咱们能够随着保持对新技术的关注,尝试这些新特性运用到实际项目中,只有这样,咱们解决问题的方案才会愈来愈完善。

到写这篇文章为止,虽然还有那么一两款机型不支持vw,但并不影响咱们去使用。只有不断去尝试,才会有进步。在此,但愿你们大胆尝试,一块儿让该方案变得更完美。若是你有更好的建议,或者你踩到任何坑,欢迎在下面的评论中与我分享,或者发邮件给我一块儿讨论。

相关文章
相关标签/搜索