[TOC]
# 移動適配方案(二)
上一篇介紹了像素和視口這些基本概念,現在接著移動端的適配方案。
之前做過PC頁面的人聊的最多的就是『兼容』,這是因為瀏覽器之間的差異引起的,不再多說。而移動端是基本沒有『兼容』的問題的,全是CSS3,簡直不要太開心。可是『適配』問題隨之而來。
## 什么是『適配』?
做PC頁面的時候,我們按照設計圖的尺寸來就好,這個側邊欄200px,那個按鈕50px的。可是,當我們開始做移動端頁面的時候,設計師給了一份寬度為640px的設計圖。那么,我們把這份設計圖實現在各個手機上的過程就是『適配』。
## 目前有三種方法
那么,我們怎么開始呢?目前有三種方法:
* 固定高度,寬度自適應
* 固定寬度,viewport縮放
* rem做寬度,viewport縮放
這三種方法的核心都是視口的確定,現在以實現這個設計圖為例說明。

### 固定高度,寬度自適應
[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調整頁面的縮放值,進而達到高清效果。

這么設置的好處是可以讓不同設備的`rem`或`px`都顯示一樣的長度。
#### 設置rem
設置rem的意義在于得到一個與屏幕寬度相關的單位,本來css3的新單位 vw,vh 是最合適的,可惜這個單位目前還有很多瀏覽器不支持,只能使用rem來做。**這樣,讓不同設備的rem顯示一樣的長度。**
>css3的新單位 vw,vh。1vw 表示可視區寬度(屏幕的可視區域即布局區域)的1%,1vh 等于可視區高度的 1%

上面的布局我們可以這樣:
```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