移動端中適配問題

原文:https://blog.csdn.net/songluyi/article/details/79447035 、https://www.jianshu.com/p/8300a5ec6480css

一直想完全理解下關於移動端適配的幾個問題點,整理以下:html

1、單位ios

首先貼上圖算法

關於單位"物理像素、邏輯像素、物理分辨率、邏輯分辨率、實際像素、css像素、設備像素、ppi、pt、dpr。"看起來有這麼多,其實只須要記住下面4個;app

一、物理像素(physical pixel):顯示器上最小的物理顯示單位。(通常來講在人眼可識別下物理像素越高,屏幕就清晰。)iphone

二、設備獨立像素(density-independent pixel) : 這個是計算機座標系統裏的虛擬慨念,這個點表明一個能夠由程序使用的虛擬像素(好比: css像素),其實就是跟手機大小相關。即邏輯像素、css像素、實際像素...ide

三、設備像素比(device pixel ratio) : 也叫dpr。 設備像素比 = 物理像素 / 設備獨立像素 。你也能夠經過window.devicePixelRatio獲取設備像素比函數

四、位圖像素 : png, jpg, gif這類都是位圖,位圖像素就是位圖的最小數據單元佈局

例如:字體

iphone6:物理像素分辨率:750*1334 

                 設備獨立分辨率:375*667

                 設備像素比:2

2、rem

rem的原理:好比width:2rem;那麼2rem究竟表示多少呢?這個和根元素html的font-size屬性相關,若是font-size爲75px,那麼2rem就表示150px。因此只要html的font-size能夠根據屏幕的尺寸和dpr動態的變化,那麼全部以rem爲單位的元素都會動態變化。至於屏幕的尺寸和dpr均可以經過js或者css獲取。

一、高清屏上位圖的處理

常見的位圖:png、jpg、gif等類型的圖片。只有一個位圖像素對應一個物理像素時,位圖纔會被高質量的顯示。

因此就會遇到:png圖片在普通屏幕上正常顯示,在高清屏幕上,就會出現像素不夠的狀況,致使圖片模糊。

比較好的解決方案:1)根據不一樣的dpr,顯示不一樣的位圖;2)不用位圖,改用矢量圖、字體圖標、轉成base64.

 

二、高清屏上border:1px的處理。

若是retina屏下的1px,也就是普通屏幕下的0.5px。

但問題是: 並非手機端屏幕都支持0.5px,ios7之下或者安卓機均可能把0.5解析成0px

這裏給到一種解決方案: 設置initial-scale=0.5

<meta name="viewport" content="width=640,initial-scale=0.5,maximum-scale=0.5, minimum-scale=0.5,user-scalable=no"

這樣,頁面中的全部的border: 1px都將縮小0.5,從而達到border: 0.5px;的效果。

然而,頁面scale,必然會帶來一些問題:

1)字體大小會被縮放

2)頁面佈局會被縮放(如: div的寬高等) 

 

三、移動端屏幕的自動適配的處理

      rem原理:根據手機的屏幕尺寸和dpr,動態修改html的font-size(基準值)

     求rem 

1 rem = document.documentElement.clientWidth * dpr / 10
(1) 乘以dpr,是由於頁面有可能爲了實現1px border頁面會縮放(scale) 1/dpr 倍(若是沒有,dpr=1),。
(2) 除以10,是爲了取整,方便計算(理論上能夠是任何值)

求iphone6的1rem 例子:

iphone6的 1rem : 375px * 2 / 10 = 75px

知道1rem是多少後,如何寫其餘的css呢?

好比width: 150px, 咱們就能夠寫成2rem

實際上,咱們每每經過一個px2rem的函數,來作轉換。算法就是 設計稿上某個div的寬度值 / 1rem的像素值, 例如 : 150px / 75px = 2rem

四、 移動端屏幕上字體大小的處理
移動端上,關於字體大小的需求,通常都是但願各個屏幕的字體都是保持同樣大的。

通常解決方案,就是根據dpr,設置不一樣的font-size,讓字體大小保持一致

方法一、用js來控制html的font-size:計算font-size值時多一步判斷來進行頁面font-size的reset。

(function(_D){
        var _self = {};
        _self.resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
        _self.Html = _D.getElementsByTagName("html")[0];
        _self.widthProportion = function(){
            var p = Number((_D.body&&_D.body.clientWidth||_self.Html.offsetWidth)/720).toFixed(3);
            return p>1.067?1.067:p<0.444?0.444:p;
        };
        _self.changePage = function(){
            _self.Html.setAttribute("style","font-size:"+_self.widthProportion()*100+"px");
            _self.correctPx();
        };
        _self.correctPx = function(){
            var docEl = document.documentElement;
            var clientWidth = docEl.clientWidth;
            if (!clientWidth || clientWidth > 768) return;
            var div = document.createElement('div');
            div.style.width = '1.4rem';
            div.style.height = '0';
            document.body.appendChild(div);
            var ideal = 140 * clientWidth / 720;
            var rmd = (div.clientWidth / ideal);
            console.log(rmd);
            if(rmd > 1.2 || rmd < 0.8){
                docEl.style.fontSize = 100 * (clientWidth / 720) / rmd + 'px';
                document.body.removeChild(div);
            }

        };
        _self.changePage();
        if (!document.addEventListener) return;
        window.addEventListener(_self.resizeEvt,_self.changePage,false);
        document.addEventListener('DOMContentLoaded', _self.changePage, false);
})(document);

五、移動端頁面的寬度範圍。

#indexContainer{
    width: 100%;
    min-width: 320px;
    max-width: 768px;
    min-height: 100%;
    font-size: .24rem;
    overflow-y: hidden;
    background-image: url(../../common/images/indexBg.png);
    background-position: 50% 0;
    background-size: 100% 100%;
    background-repeat: no-repeat;
}
相關文章
相關標籤/搜索