[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方案
- 前言
- 中文字体
- 移动Web适配方案
- !移动Web基础!
- 详解适配相关概念
- 移动开发之设计稿
- 移动适配方案(一)
- 移动适配方案(二)
- vw+rem 实现移动端布局
- 移动端适配之雪碧图(sprite)背景图片定位
- 适配 iPhoneX
- 前端开发实战
- 打造自己的前端开发流程(Gulp)
- flexible.js案例讲解
- viewport 与 flexible.js解读
- 图片与字体
- 踩过的坑
- 浏览器默认样式
- 300ms点击延迟和点击穿透
- ios css
- CSS 常见问题
- Ionic v1混合开发
- Native App、Web App 、Hybrid App?
- ionic项目结构
- 混淆加密
- 解决问题
- cordova
- 环境配置
- 打包发布
- 问题
- 移动前端开发优化
- Web开发之抓包
- ===web移动开发资源===
- H5组件框架
- 调试集合
- 简单h5调试
- whistle
- devtools-pro