移動端適配

前言:這周工做碰到了移動端1px的問題。之前一直寫樣式也沒有特別注意着一點。還有就是rem的原理。這些其實就是比較常見的移動端適配問題。現階段比較主流的適配方案有二種。一種是flexible + rem,另外一種是vwcss

下面咱們來看一下具體狀況html

一、基本概念

在瞭解具體方案原理前,咱們先來看一下一些基本概念:html5

1.一、物理像素(physical pixel)

物理像素又被稱爲設備像素,他是顯示設備中一個最微小的物理部件。每一個像素能夠根據操做系統設置本身的顏色和亮度。git

1.二、設備獨立像素(density-independent pixel)

設備獨立像素也稱爲密度無關像素,能夠認爲是計算機座標系統中的一個點,這個點表明一個能夠由程序使用的虛擬像素(好比說CSS像素),而後由相關係統轉換爲物理像素。(老早在沒有 retina 屏以前,設備獨立像素與物理像素是相等的)github

1.三、CSS像素

CSS像素是一個抽像的單位,主要使用在瀏覽器上,用來精確度量Web頁面上的內容。通常狀況之下,CSS像素稱爲與設備無關的像素(device-independent pixel),簡稱DIPs。web

1.四、設備像素比(device pixel ratio)

設備像素比簡稱爲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

1.五、rem

簡單的理解,rem就是相對於根元素<html>font-size來作計算。而咱們的方案中使用rem單位,是能輕易的根據<html>ont-size計算出元素的盒模型大小。而這個特點對咱們來講是特別的有益處。app

二、flexible實現方案

瞭解了前面一些相關概念以後,接下來咱們來看實際解決方案。淘寶有一個名叫lib-flexible的庫,而這個庫就是用來解決H5頁面終端適配的。 咱們把屏幕分紅10等分,那麼iphone

  • 物理像素爲 750 = 375 * 2,那麼 10rem = 750px,1rem = 75px;
  • 物理像素爲 1125 = 375 * 3,那麼 10rem = 1125px,1rem = 112.5px ;
  • 物理像素爲 1242 = 414 * 3, 那麼 10rem = 1242px,1rem = 124.2px;
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;
    }
複製代碼

2.一、1px的物理像素的解決方案

由此咱們獲得一個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 的不一樣設置而改變。

  • 一、vw : 1vw 爲視口寬度的 1%
  • 二、vh : 1vh 爲視口高度的 1%
  • 三、vmin : vw 和 vh 中的較小值
  • 四、vmax : 選取 vw 和 vh 中的較大值

若是設計稿爲 750px,那麼 1vw = 7.5px,100vw = 750px。其實設計稿按照設麼都沒多大關係,最終轉化過來的都是相對單位,上面講的 rem 也是對它的模擬。

跟以前同樣的痛點,咱們仍然須要花費大量沒必要要的計算時間去把標註圖中的px轉換爲vw,有沒有相似於postcss-px2rem的工具呢?很榮幸能再次站在巨人的肩膀上,已經有大神寫了了相似的PostCss插件 postcss-px-to-viewport

本身學習時的一點小總結,若有問題,歡迎指正。

參看資料 www.w3cplus.com/mobile/lib-…

相關文章
相關標籤/搜索