前言:這周工做碰到了移動端1px的問題。之前一直寫樣式也沒有特別注意着一點。還有就是rem的原理。這些其實就是比較常見的移動端適配問題。現階段比較主流的適配方案有二種。一種是
flexible + rem
,另外一種是vw
css
下面咱們來看一下具體狀況html
在瞭解具體方案原理前,咱們先來看一下一些基本概念:html5
物理像素又被稱爲設備像素,他是顯示設備中一個最微小的物理部件。每一個像素能夠根據操做系統設置本身的顏色和亮度。git
設備獨立像素也稱爲密度無關像素,能夠認爲是計算機座標系統中的一個點,這個點表明一個能夠由程序使用的虛擬像素(好比說CSS像素),而後由相關係統轉換爲物理像素。(老早在沒有 retina 屏以前,設備獨立像素與物理像素是相等的)github
CSS像素是一個抽像的單位,主要使用在瀏覽器上,用來精確度量Web頁面上的內容。通常狀況之下,CSS像素稱爲與設備無關的像素(device-independent pixel),簡稱DIPs。web
設備像素比簡稱爲dpr,其定義了物理像素和設備獨立像素的對應關係。它的值能夠按下面的公式計算獲得:瀏覽器
設備像素比 = 物理像素 / 設備獨立像素
複製代碼
在JavaScript
中,能夠經過window.devicePixelRatio
獲取到當前設備的dpr
。而在CSS中,能夠經過-webkit-device-pixel-ratio
,-webkit-min-device-pixel-ratio
和 -webkit-max-device-pixel-ratio
進行媒體查詢,對不一樣dpr
的設備,作一些樣式適配(這裏只針對webkit內核的瀏覽器和webview) 所以在iphone 六、七、8 的 dpr 爲 2的設備中,一個設備獨立像素便爲 4 個物理像素,所以在 css 上設置的 1px 在其屏幕上佔據的是 2個物理像素,0.5px 對應的纔是其所能展現的最小單位。bash
簡單的理解,rem
就是相對於根元素<html>
的font-size
來作計算。而咱們的方案中使用rem
單位,是能輕易的根據<html>
的ont-size
計算出元素的盒模型大小。而這個特點對咱們來講是特別的有益處。app
瞭解了前面一些相關概念以後,接下來咱們來看實際解決方案。淘寶有一個名叫lib-flexible的庫,而這個庫就是用來解決H5頁面終端適配的。 咱們把屏幕分紅10等分,那麼iphone
function refreshRem(){
var width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {
width = 540 * dpr;
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}
複製代碼
由此咱們獲得一個1px像素的解決方案。viewport 的 initial-scale 具備縮放頁面的效果。對於 dpr=2 的屏幕,1px壓縮一半即可與1px的設備像素比匹配,這就能夠經過將縮放比 initial-scale 設置爲 0.5=1/2 而實現。以此類推 dpr=3的屏幕能夠將 initial-scale設置爲 0.33=1/3 來實現。
<meta name="viewport" content="width=device-width, initial-scale=0.5, maximum-scale=0.5">
複製代碼
if (!metaEl) {
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
} else {
var wrap = doc.createElement('div');
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
}
複製代碼
將視口寬度 window.innerWidth 和視口高度 window.innerHeight 等分爲 100 份,且將這裏的視口理解成 idealviewport 更爲貼切,並不會隨着 viewport 的不一樣設置而改變。
若是設計稿爲 750px,那麼 1vw = 7.5px,100vw = 750px。其實設計稿按照設麼都沒多大關係,最終轉化過來的都是相對單位,上面講的 rem 也是對它的模擬。
跟以前同樣的痛點,咱們仍然須要花費大量沒必要要的計算時間去把標註圖中的px轉換爲vw,有沒有相似於postcss-px2rem的工具呢?很榮幸能再次站在巨人的肩膀上,已經有大神寫了了相似的PostCss插件 postcss-px-to-viewport
本身學習時的一點小總結,若有問題,歡迎指正。