移動端適配你瞭解多少(二)

在網上搜了一下,不少面試都會被問到移動端適配方法的問題,最近看了一些文章,這裏總結一下。css

首先,談一下目前爲止出現的一些關於移動端適配的技術方案:web

 1. 經過媒體查詢的方式即CSS3的meida queries 2. 以天貓首頁爲表明的 flex 彈性佈局  

 3. 以淘寶首頁爲表明的 rem+viewport縮放 4. rem 方式

1.Media Queries

meida queries 的方式能夠說是我早期採用的佈局方式,它主要是經過查詢設備的寬度來執行不一樣的 css 代碼,最終達到界面的配置。核心語法是:面試

@media screen and (max-width: 600px)
 { /*當屏幕尺寸小於600px時,應用下面的CSS樣式*/
  /*你的css代碼*/}

優勢瀏覽器

  • media query能夠作到設備像素比的判斷,方法簡單,成本低,特別是對移動和PC維護同一套代碼的時候。目前像Bootstrap等框架使用這種方式佈局
  • 圖片便於修改,只需修改css文件
  • 調整屏幕寬度的時候不用刷新頁面便可響應式展現

缺點sass

  • 代碼量比較大,維護不方便
  • 爲了兼顧大屏幕或高清設備,會形成其餘設備資源浪費,特別是加載圖片資源
  • 爲了兼顧移動端和PC端各自響應式的展現效果,不免會損失各自特有的交互方式

2.Flex彈性佈局

以天貓的實現方式進行說明:框架

它的viewport是固定的:<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">。
這裏寫圖片描述
在這裏插入圖片描述iphone

高度定死,寬度自適應,元素都採用px作單位。ide

隨着屏幕寬度變化,頁面也會跟着變化,效果就和PC頁面的流體佈局差很少,在哪一個寬度須要調整的時候使用響應式佈局調調就行(好比網易新聞),這樣就實現了『適配』。工具

3.rem + viewport 縮放

這也是淘寶使用的方案,根據屏幕寬度設定 rem 值,須要適配的元素都使用 rem 爲單位,不須要適配的元素仍是使用 px 爲單位。(1em = 16px)佈局

PS:rem 
rem是CSS3新增的一個相對單位(root em,根em),這個單位引發了普遍關注。這個單位與em有什麼區別呢?
區別在於使用rem爲元素設定字體大小時,仍然是相對大小,但相對的只是HTML根元素。這個單位可謂集相對大小和絕對
大小的優勢於一身,經過它既能夠作到只修改根元素就成比例地調整全部字體大小,又能夠避免字體大小逐層複合的連鎖
反應。目前,除了IE8及更早版本外,全部瀏覽器均已支持rem。對於不支持它的瀏覽器,應對方法也很簡單,就是多寫一
個絕對單位的聲明。這些瀏覽器會忽略用rem設定的字體大小。好比:p{font-size:14px;font-size:0.875rem;}
(推薦一個單位轉換的工具:http://pxtoem.com/)

實現原理
根據rem將頁面放大dpr倍, 而後viewport設置爲1/dpr.

如iphone6 plus的dpr爲3, 則頁面總體放大3倍, 1px(css單位)在plus下默認爲3px(物理像素)
而後viewport設置爲1/3, 這樣頁面總體縮回原始大小. 從而實現高清。

這裏寫圖片描述
在這裏插入圖片描述
mobile-fe4.png
這裏寫圖片描述
在這裏插入圖片描述
mobile-fe3.png

這樣整個網頁在設備內顯示時的頁面寬度就會等於設備邏輯像素大小,也就是device-width。
這個device-width的計算公式爲:設備的物理分辨率/(devicePixelRatio * scale),
在scale爲1的狀況下,device-width = 設備的物理分辨率/devicePixelRatio 。

四、rem實現

好比說「魅族」移動端的實現方式,viewport也是固定的:
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">。

經過如下代碼來控制rem基準值(設計稿以720px寬度量取實際尺寸)

!function (d) {var c = d.document;var a = c.documentElement;var b = d.devicePixelRatio;var f;function e() {  var h = a.getBoundingClientRect().width, g;  if (b === 1) {h = 720  }  if(h>720) h = 720;//設置基準值的極限值  g = h / 7.2;  a.style.fontSize = g + "px"}if (b > 2) {  b = 3} else {  if (b > 1) {b = 2  } else {b = 1  }}a.setAttribute("data-dpr", b);d.addEventListener("resize", function () {  clearTimeout(f);  f = setTimeout(e, 200)}, false);e()
  }(window);

css經過sass預編譯,設置量取的px值轉化rem的變量$px: (1/100)+rem;
這裏寫圖片描述
在這裏插入圖片描述

像素邊框高清

1.淘寶實現方式

上面說到的淘寶的實現方式即rem+viewport 縮放來實現。

transform: scale(0.5)

CSS代碼:

div{width: 1px;height: 100%;display: block;border-left: 1px solid #e5e5e5;-webkit-transform: scale(.5);transform: scaleX(.5);}

缺點:

圓角沒法實現,實現4條邊框比較麻煩,而且只能單獨實現,若是嵌套,會對包含的效果產生不想要的效果,因此此方案配合:after和before獨立使用較多。

1.1.box-shadow

實現方法:
利用CSS對陰影處理的方式實現0.5px的效果。

-webkit-box-shadow:0 1px 1px -1px rgba(0, 0, 0, 0.5);

優勢:

基本全部場景都能知足,包含圓角的button,單條,多條線。

缺點:

顏色很差處理, 黑色 rgba(0,0,0,1) 最深的狀況了。有陰影出現,很差用。
大量使用box-shadow可能會致使性能瓶頸。
四條邊框實現效果不理想。

2.圖片實現

使用 background-image 實現1px有兩種方式: 漸變 linear-gradient 或直接使用圖片(base64)。

漸變 linear-gradient (50%有顏色,50%透明)

單條線:

div{height: 1px;background-image:-webkit-linear-gradient(top,transparent 50%,#000 50%);background-position: top left;background-repeat: no-repeat;background-size: 100% 1px;}

多線條:

div{background-image: -webkit-linear-gradient(top,transparent 50%,#000 50%),-webkit-linear-gradient(bottom, transparent 50%, #000 50%),-webkit-linear-gradient(left, transparent 50%, #000 50%),-webkit-linear-gradient(right, transparent 50%, #000 50%);background-size: 100% 1px,100% 1px,1px 100%,1px 100%;background-repeat: no-repeat;background-position: top left, bottom left, left top, right top;
  }

優勢:

  • 能夠設置單條,多條邊框
  • 能夠設置顏色

缺點:

  • 大量使用漸變可能致使性能瓶頸
  • 代碼量大
  • 多背景圖片有兼容性問題