移動端佈局方案淺談

media+百分比

直接採用媒體查詢加百分比去佈局。javascript

核心思想:css

  • 頁面主體佈局基本採用百分比去設置。html

  • 而後,其餘塊內佈局,例如font-size等可經過設置媒體查詢的斷點來分設置,已達到兼容其餘手機尺寸。java

優勢:android

  • 靈活,簡單ios

  • 兼容性好,媒體查詢,97.65%的瀏覽器都支持了。git

缺點:github

  • 媒體查詢的斷點設置麻煩,只能在選取的幾個主流設備尺寸下呈現完美適配。瀏覽器

  • 1px的問題,須要額外作處理,好比transform:scaleX(0.5)app

例子:京東

圖片描述

hotcss

這個方案比較簡單和實用,理解起來也不難。

原理:

  • 自動經過hotcss.js計算頁面的htmlfont-size的大小,其後在佈局中使用rem做爲像素單位,使得頁面在不一樣的移動設備上能夠視覺一致。

  • 經過獲取dpr,在html上設置屬性data-dpr,在設置font-size時,能夠配合data-dpr來使用px做爲像素單位。

  • 計算scale,爲頁面設置viewport,使得頁面根據dpr進行縮放,最終達到,1個物理像素=1px。這樣,也有效解決了1px的問題。

  • 默認在320px屏幕中(非Retina屏),1rem=20px;

核心源碼:

  • 計算dpr並設置data-dprscale

    //計算dpr
    var dpr=window.devicePixelRatio||1;
    //在其餘的一些方案中,會區分ios和android,對android統一設置爲1.
    dpr=dpr>=3?3:(dpr>=2?2:1);
    //設置data-dpr
    document.documentElement.setAttribute('data-dpr',dpr); 
    //計算scale
    var scale=1/dpr,
        content='width=device-width,initial-scale='+scale+',minimum-scale='+scale+',maximum-scale='+scale+',user-scalable=no';
    //插入meta,設置頁面縮放 
    var viewport=document.createElement('meta');
    viewport.setAttribute('name','viewport');
    viewport.setAttribute('content',content);
    document.head.appendChild(viewport);
  • 計算font-size並設置htmlfont-size

    //獲取設備的寬度
    var innerWidth=document.documentElement.getBoundingClientRect().width||window.innerWidth;
    //計算font-seize,默認320px中,1rem=20px.
    document.documentElement.style.fontSize=(innerWidth*20/320)+'px';

優勢:

  • 後續佈局處理簡單,配合px2rem插件等,使用十分方便。

  • 基本能很好適配市面即大多數尺寸手機。

  • 兼容性也比較好,97.62%瀏覽器基本支持rem單位了。

  • 經過設置縮放比例,有效解決了1px的問題。

缺點:

  • 頁面須要額外引入js腳本去計算,增長一次額外的http請求,或內嵌到頁面中增長頁面體積大小。

例子:卷皮

圖片描述

flexible

這個是手機淘寶推出來一個方案,解決手機淘寶H5在移動端的佈局。

原理:

  • 自動經過flexible.js計算頁面htmlfont-size的大小,而後在頁面佈局中使用rem做爲單位,而非px。

  • 若是頁面指定了meta[name="viewport"],則直接根據已有的meta標籤來設置縮放比例;不然,經過dpr來自動計算頁面縮放比例。

  • 設置1rem=10vw,例如,在320px屏幕(非Retina屏),1rem=32px;

核心源碼:

  • 計算縮放比例

    //參試獲取頁面已定義的縮放比例
    var metaEl = doc.querySelector('meta[name="viewport"]');
    if(metaEl){
      console.warn('將根據已有的meta標籤來設置縮放比例');
      var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
      if (match) {
        scale = parseFloat(match[1]);
        dpr = parseInt(1 / scale);
      }
    }
    //若是沒有,則自動計算
    if (!dpr && !scale) {
        var isAndroid = win.navigator.appVersion.match(/android/gi);
        var isIPhone = win.navigator.appVersion.match(/iphone/gi);
        var devicePixelRatio = win.devicePixelRatio;
        if (isIPhone) {
          // iOS下,對於2和3的屏,用2倍的方案,其他的用1倍方案
          if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
            dpr = 3;
          } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) {
            dpr = 2;
          } else {
            dpr = 1;
          }
        } else {
          // 其餘設備下,仍舊使用1倍的方案
          dpr = 1;
        }
        scale = 1 / dpr;
    }
  • 設置meta

    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);
      }
    }
  • 計算頁面的html的font-size

    var width = docEl.getBoundingClientRect().width;
    //最大屏幕寬度爲540*dpr
    if (width / dpr > 540) {
      width = 540 * dpr;
    }
    //設置1rem=10vw
    var rem = width / 10;
    docEl.style.fontSize = rem + 'px';
    flexible.rem = win.rem = rem;

優缺點同hotcss。

例子:淘寶

圖片描述

rem+vw

這種方案就是在計算html的font-size時,是根據vw去自動計算,而不是用js腳本去動態計算。vw是一種新的單位,相似的還有vh,vmin,vmax。定義以下:

  • vw:1vw等於視口寬度的1%;例如,320px寬度視口中,1vw=3.2px,10vw=32px,100vw=320px;

  • vh:1vh等於視口高度的1%;例如,568px高度視口中,1vh=5.58px,10vh=56.8px,100vh=568px;

  • vmin:選取vw和vh中最小的那個;

  • vmax:選取vw和vh中最大的那個;

核心思想:

  • 不用js去動態計算頁面的font-size ,而是設置根元素html的font-size=?vw;這裏的?,能夠選取一種屏幕尺寸去參考計算。例如,咱們想iPhone6下,html的font-size爲100px。那個html的font-size=100/375=0.26666666666666666vw。那麼,其餘屏幕的適配計算方式就是:

    iphone5:屏幕是320*568
    html的font-size=0.26666666666666666*320=85.33333333333333
    
    iphone6s:屏幕是414*736
    html的font-size=0.26666666666666666*414=110.39999999999999 
  • 頁面佈局採用rem佈局,而非px。根據html的font-size和rem單位自動計算出了佈局px。

優勢:

  • 不須要額外引入js腳本去計算,自動根據vw去計算font-size

  • 後續佈局也超級簡單,採用rem便可。

缺點:

  • vw單位的支持相對比rem的瀏覽器少一些,目前有93.65%的瀏覽器都支持了。

例子:拼多多

圖片描述

相關文章
相關標籤/搜索