移動端配置

物理像素

iphone 6 的寬度有750給物理像素

邏輯像素

也叫設備的獨立像素,css像素也是邏輯像素的一種

邏輯像素比(dpr)

物理像素➗邏輯像素,iphone6 的dpr=2

常見問題

  • 圖片模糊
  • 1px問題

1.圖片模糊

一個圖片大小200px * 200px(邏輯像素) 在dpr爲1的屏幕下顯示正常,在dpr爲2的情況下那麼在200px * 200px(邏輯像素)下物理像素是400px * 400px(物理像素)

本來一個物理像素點就好了現在變成了(2*2)個,那麼問題來了,其他的物理像素點會去找相近的顏色去填充,所以就變的模糊了

2.1px問題

這個問題很有意思,真的給我上了一課以後看文章,真的要多看一些在做出選擇爲什麼呢?

網上很多人的說法:因爲dpr>1所以導致邊框線變粗,我就很奇怪1px變粗,那爲什麼沒有2px問題,3px問題,4px問題...,爲什麼2px,3px,4px不會變粗,然道他們的dpr不是>1嗎?明顯他們就說錯了,但是哇,就很誇張很多人寫的都是因爲dpr的原因?

我認爲:其實就是在一個750px的設計圖上的邊框爲1px那麼按照比例在iphone6-375px-下顯示的的邊框按比例是0.5px其實就是作用而已,其實有些公司會把這個1px在移動端變成.5px(阿里巴巴,JD)都是變了的,但是也有沒有變的爲什麼呢?應爲其實邊框本來就是不支持百分比的所以其實我認爲按照css規範其實設計圖1px那麼不管在什麼屏幕下應該都是1px,而不是去縮放邊框(閱文的官網,google)我看的就是1px還是1px,其實這個和UI說的算的咯,解決就網上好多文章哈哈

國內知名互聯網企業移動端H5尺寸適配方案

1.很多年前淘寶的lib-flexible移動端配置方案

原理:通過dpr,去動態生成縮放視口,從而邏輯像素等於物理像素,那麼在動態生成html下的字體大小就可以控制rem了,比如在750的設計稿下,一個div爲75px,那麼我們可以1rem,

縮放視圖

var scale = 1 / devicePixelRatio;
document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

根據不同移動設備動態計算font-size

document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';

但是這個已經被淘汰了,由於viewport單位得到衆多瀏覽器的兼容,lib-flexible這個過渡方案已經可以放棄使用

JD

    /* JD的移動端刷屏 */
    html {
      font-size: 20px;
      font-size: 5.33333vw
        /* 3.75px * 5.33333 ~ 20px */
    }

    @media screen and (max-width:320px) {
      html {
        font-size: 17.06667px
      }
    }

    @media screen and (min-width:540px) {
      html {
        font-size: 28.8px
      }
    }

其實這個就很有意思,不會根據屏幕大小改變一點就去變一點,而是在一個範圍,然後再彈性佈局

百度

html {
    font-size: 100px
}

@media screen and (max-width: 360px) {
    html {
        font-size:90px;
        line-height: 90px
    }
}

body {
    font-size: 16px;
}

網易

(1)以iphone6作爲參照,iphone6的寬度是375px,dpr爲2,所以對於上面顯示的375px的圖,我們需要的圖片大小是750px,所以我們拿到的psd設計圖的寬度必須是750px。爲了方便書寫rem,我們希望psd設計圖上750px對應的rem是7.5rem。而設計圖上面750px在iphone6上面的實際大小是375px,所以我們需要設置iphone6的font-size=375/7.5px=50px。更一般地,由於移動端的font-size的默認值是16px,所以我們更傾向於用一個百分比來設置font-size:font-size=50/16=312.5%。(注意:用px和百分比沒有本質上的不同。)

(2)在其它屏幕上進行縮放,爲了解決這個問題,我們用js來讀取屏幕的寬度,然後利用這個寬度來進行縮放,代碼如下:

var initScreen=function(){
    $("html").css("font-size", document.documentElement.clientWidth / 375 * 312.5 + "%");
}

最後,我們需要解決橫屏問題和用戶手動縮放問題,他們本質上都是改變屏幕寬度的問題,所以我們監聽resize事件或者onorientationchange事件,當發生的時候,重新調用initScreen方法。代碼如下:

$(window).on('onorientationchange' in window ? 'orientationchange' : 'resize', function () {
    setTimeout(initScreen, 200);
});

注意:上面的代碼並不是原生js,要引入zepto庫!也可以用原生js實現,不過要考慮兼容性問題,我就不貼出代碼了。

注意:我這種適配方案中,1rem的實際大小是50px,而不是100px。所以0.12rem的字體,在設計稿上面是12px,但是在手機上的實際大小是6px

另外,爲了增加代碼的健壯性,在js加載不成功的時候也能進行適配,建議在css加上媒體查詢:

@media screen and (max-width: 320px) {
    html {
        font-size:42.667px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 321px) and (max-width:360px) {
    html {
        font-size:48px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 361px) and (max-width:375px) {
    html {
        font-size:50px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 376px) and (max-width:393px) {
    html {
        font-size:52.4px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 394px) and (max-width:412px) {
    html {
        font-size:54.93px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 413px) and (max-width:414px) {
    html {
        font-size:55.2px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 415px) and (max-width:480px) {
    html {
        font-size:64px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 481px) and (max-width:540px) {
    html {
        font-size:72px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 541px) and (max-width:640px) {
    html {
        font-size:85.33px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 641px) and (max-width:720px) {
    html {
        font-size:96px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 721px) and (max-width:768px) {
    html {
        font-size:102.4px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 769px) {
    html {
        font-size:102.4px;
        font-size: 13.33333vw
    }
}

目前淘寶

    解讀

 

1.開始函數先來匿名函數

2.找到HTML文檔對象,因爲後面要給他定義fontSize的值;

3.找到dpr的值,如果大於等於2,就給這個設備設置0.5px的邊框

4.除以3.75的解釋:如果設計圖爲750那麼就是除以7.5爲什麼是7.5 ? 因爲我們以100px爲1rem那麼750的設計圖爲7.5rem,那麼我們要求出不同設備的rem的值就是用n.clientWidth/7.5就是rem的值

5.函數i給html定義fontSize的值

6.最後if()中的條件: 

        6-1:判斷 是否存在document.body 再設置html標籤的font-size的值

        6-2:設置html標籤的font-size的值,

        6-3:設置監聽橫屏事件,和判斷是否是緩存 

        6-4:最後判斷drp的值:是否設置.5px的邊框

 7.if{}中的代碼是判斷是否支持.5px,支持添加屬性hairlines

    // 解讀
    // e = window ; t = document
    // n === document.documentElement 是一個會返回文檔對象(document)的根元素的只讀屬性(如HTML文檔的 <html> 元素 
    //  d === window.devicePixelRatio 返回當前顯示設備的dpr 
    // 這裏 / 3.75 的解釋
    // 設計圖以iPhone6的分辨率爲標準(750x1334)
    // 把上面代碼中的3.75改爲7.5(如果設計圖以375x667爲標準則不用改)
    // 前端寫CSS時把設計圖的單位統一以除以100,然後使用rem單位。
    !function (e, t) {
      var n = t.documentElement // document.documentElement
        , d = e.devicePixelRatio || 1; // dpr
      function i() {
        var e = n.clientWidth / 3.75;
        n.style.fontSize = e + "px"
      }

      // 判斷 是否存在document.body 再設置html標籤的font-size的值,監聽橫屏事件,和判斷是否是緩存,和判斷drp的值
      if (function e() {
        t.body ? t.body.style.fontSize = "16px" : t.addEventListener("DOMContentLoaded", e)
      }(),
        i(),
        e.addEventListener("resize", i), // 當屏幕變成橫屏的時候觸發事件
        // onpageshow 事件類似於 onload 事件,onload 事件在頁面第一次加載時觸發, onpageshow 事件在每次加載頁面時觸發,即 onload 事件在頁面從瀏覽器緩存中讀取時不觸發
        e.addEventListener("pageshow", function (e) {
          // e.persisted : 返回boolead類型 是否是來自緩存數據,如果是那麼也會觸發i()
          e.persisted && i()
        }),
        // 當 drp 大於等於2的時候
        2 <= d) {
        // 以下代碼是再處理.5xp的兼容問題 
        // createElement//創建元素節點
        var o = t.createElement("body")
          , a = t.createElement("div");
        a.style.border = ".5px solid transparent",
          // appendChild//讓他成爲這個文檔現有節點的一個子節點
          o.appendChild(a),
          n.appendChild(o),
          // offsetHeight 元素再垂直方向上的時間 offsetHeight=height+padding+border 
          // 判斷是否支持.5px支持,添加屬性
          // classList.add 添加屬性  
          1 === a.offsetHeight && n.classList.add("hairlines"),
          // removeChild() //方法可從子節點列表中刪除某個節點
          n.removeChild(o)
      }
    }(window, document)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章