🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 移动适配方案(二) 上一篇介绍了像素和视口这些基本概念,现在接着移动端的适配方案。 之前做过PC页面的人聊的最多的就是『兼容』,这是因为浏览器之间的差异引起的,不再多说。而移动端是基本没有『兼容』的问题的,全是CSS3,简直不要太开心。可是『适配』问题随之而来。 ## 什么是『适配』? 做PC页面的时候,我们按照设计图的尺寸来就好,这个侧边栏200px,那个按钮50px的。可是,当我们开始做移动端页面的时候,设计师给了一份宽度为640px的设计图。那么,我们把这份设计图实现在各个手机上的过程就是『适配』。 ## 目前有三种方法 那么,我们怎么开始呢?目前有三种方法: * 固定高度,宽度自适应 * 固定宽度,viewport缩放 * rem做宽度,viewport缩放 这三种方法的核心都是视口的确定,现在以实现这个设计图为例说明。 ![](https://box.kancloud.cn/afb4a10235dfc4e1ba755de12ba43f0a_640x148.png) ### 固定高度,宽度自适应 [demo](http://www.meow.re/demo/screen-adaptation-in-mobileweb/app-fixed-height.html) 这也是目前使用最多的方法,垂直方向用定值,水平方向用百分比、定值、flex都行。腾讯、京东、百度、天猫、亚马逊的首页都是使用的这种方法。 随着屏幕宽度变化,页面也会跟着变化,效果就和PC页面的流体布局差不多,在哪个宽度需要调整的时候使用_响应式布局_调调就行(比如网易新闻),这样就实现了『适配』。 #### 原理 这种方法使用了完美视口: ```html <meta name="viewport" content="width=device-width,initial-scale=1"> ``` 这样设置之后,我们就可以不用管手机屏幕的尺寸进行开发了。 ### 固定宽度,viewport缩放 [demo](http://www.meow.re/demo/screen-adaptation-in-mobileweb/app-fixed-width.html) 设计图、页面宽度、viewport width使用一个宽度,浏览器帮我们完成缩放。单位使用px即可。 目前已知荔枝FM、网易新闻在使用这种方法。有兴趣的同学可以看看是怎么做的。 #### 原理 这种方法需要根据屏幕宽度来动态生成viewport,生成的 viewport 基本是这样: ```html <meta name="viewport" content="width=640,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no"> ``` 640 是我们根据设计图定下的,0.5 是根据屏幕宽度动态生成的。 生成的viewport告诉浏览器网页的布局视口使用 640px,然后把页面缩放成50%,这是绝对的等比例缩放。图片、文字等等所有元素都被缩放在手机屏幕中。 ### rem做宽度,viewport缩放 [demo](http://www.meow.re/demo/screen-adaptation-in-mobileweb/app-rem.html) 这也是淘宝使用的方案,根据屏幕宽度设定 rem 值,需要适配的元素都使用 rem 为单位,不需要适配的元素还是使用 px 为单位。 具体使用方法见使用Flexible实现手淘H5页面的终端适配 上文提供了sass 和 postcss的 px2rem转换方法,我这里给出 less的 px2rem。因为 less 不支持函数,所以需要安装插件 less-plugin-functions ,然后就简单了: ```css .function{ .px2rem(@px,@base:72px){ return: @px / @base * 1rem; } } ``` 这样使用: ```css div{ width: px2rem(100px); } ``` 使用这个方法的库: [lib-flexible](https://github.com/amfe/lib-flexible) [hotcss](https://github.com/imochen/hotcss) #### 原理 实际上做了这几件事情: * 动态生成 `viewport` * 屏幕宽度设置 rem的大小,即给`<html>`设置`font-size` * 根据设备像素比(`window.devicePixelRatio`)给`<html>`设置`data-dpr` 即:动态设置 html 的font-size, 同时根据设备DPR调整页面的缩放值,进而达到高清效果。 ![](https://box.kancloud.cn/da920d9c414f3249c0046c819bf77ca4_1750x288.png) 这么设置的好处是可以让不同设备的`rem`或`px`都显示一样的长度。 #### 设置rem 设置rem的意义在于得到一个与屏幕宽度相关的单位,本来css3的新单位 vw,vh 是最合适的,可惜这个单位目前还有很多浏览器不支持,只能使用rem来做。**这样,让不同设备的rem显示一样的长度。** >css3的新单位 vw,vh。1vw 表示可视区宽度(屏幕的可视区域即布局区域)的1%,1vh 等于可视区高度的 1% ![](https://box.kancloud.cn/5b4302436d6fdca488f698b7ece279ec_1348x998.png) 上面的布局我们可以这样: ```css html{ font-size: 屏幕宽度 / 10; } .btn{ width:8.75rem; height:1.25rem; } ``` 这样,无论屏幕宽度是多少,`.btn`都是相对于屏幕的这么宽,做到了适配。 设置 `viewport` 缩放 和`data-dpr` 这两个设置其实是干的一件事,就是适配高密度屏幕手机的`px`单位。 ```css .a{ font-size:12px; } [data-dpr="2"] .a{ font-size: 24px; } [data-dpr="3"] .a{ font-size: 36px; } ``` 而缩放是动态的,这样,不同设备下的`px`显示一样的长度。 之前说过CSS像素和物理像素与缩放、`dpr`都有关系,这里说明: >在普通手机上,`.a`字体设置为12px; >在`dpr`是2的手机上,`[data-dpr="2"] .a`字体为`24px`,又因为页面缩放50%,字体为还是`12px` ## 视窗单位(vw,vh,vmin,vmax) 视窗单位非常有趣。它们使你可以根据视窗的尺寸大小控制字体的 `font-size` 。如果使用得当,它们还可以避免通过不同断点设置字体大小的实现代码。这是因为这些单位值会随着视窗的高度、宽度做连续性的变化。 ~~~ vw —— viewpoint width,视窗宽度,1vw等于视窗宽度的1%; vh —— viewpoint height,视窗高度,1vh等于视窗高度的1%; ~~~ 例如,`1vw`在视窗为`400px`宽时是`4px`,在视窗宽度为`1000px`时,就变成了`10px`。SitePoint(sina邮箱登陆)上已经有一篇文章专门讨论 [视窗单位和它们的应用场景](https://www.sitepoint.com/css-viewport-units-quick-start/) 。想了解的话可以去看一下那篇文章。 参加 [CodePen](http://codepen.io/) 上的 [使用视窗单位设置字体大小](https://codepen.io/SitePoint/pen/EmLNVv/) 的例子。(By [@SitePoint](http://codepen.io/SitePoint) )。 使用视窗单位的问题就是计算出的 `font-size` 可能会让字体不适合阅读,字体有可能非常小或者非常大。一个小技巧就是在使用视窗单位的同时,也使用其他字体设置,避免字体过大或者过小。这个技巧在 [视窗单位的基础排版](https://zellwk.com/blog/viewport-based-typography/) 一文中有具体解释。 > 如今 flexible.js 已经成了过去式,我们实现移动端自动适配,还要在 head 中添加 js 代码,对于任何一个追求完美的人确实不能忍,还好我们有 vw 和 vh,而且它们在如今大部分手机中都得到了支持 > [vw+rem 实现移动端布局](vw+rem%20%E5%AE%9E%E7%8E%B0%E7%A7%BB%E5%8A%A8%E7%AB%AF%E5%B8%83%E5%B1%80.md) ## 总结 未来应该有两个方向去自适应。 * 一个是拥抱`vw`,`vh`。(手淘的 ml.js 十等分宽度,`1rem=10vw`) * 一个是更好的使用flex 现在使用后者已经有很多的库可以解决兼容性了,如参考资源最后的一个 flex 库。 目前我唯一知道的区别就是第三种方案更加灵活,有两种单位可以使用,想让元素适配的时候就用 rem,想让文字不缩放的时候就用 px。 ## 参考 原文:https://github.com/riskers/blog/issues/18 [移动端适配知识你到底知多少](https://www.mk2048.com/blog/blog.php?id=hajjic02hj) [手机端页面自适应解决方案—rem布局进阶版(附源码示例)](http://blog.csdn.net/ylhsuper/article/details/73190103) [MobileWeb 适配总结](http://www.meow.re/original/2015/04/27/screen-adaptation-in-mobileweb/) [从网易与淘宝的font-size思考前端设计稿与工作流](http://www.cnblogs.com/lyzg/p/4877277.html) [移动端高清、多屏适配方案](http://div.io/topic/1092) [手机百度移动适配切图解决方案介绍](http://js8.in/2015/12/12/手机百度移动适配切图解决方案介绍/) [移动端自适应方案](http://f2e.souche.com/blog/yi-dong-duan-zi-gua-ying-fang-an/) 介绍了 flex 布局和rem方案