移動端適配真的不難

佈局視口、視覺視口、理想視口

佈局視口(layout viewport)

佈局視口是窗口容許最大的佈局尺寸,當頁面元素超過佈局視圖時會出現橫向滾動條,瀏覽器中經過document.documentElement.clientWidth/clientHeight來獲取 css

視圖對比

視覺視圖(visual viewport)

視覺視圖是用戶可以瀏覽到的內容的寬和高,網站上不少解釋是手機的屏幕大小,經過window.innerWidth/innerHeight獲取到的結果代表並不是如此。web

理想視口(ideal viewport)

從上面知道手機可以徹底展現佈局視口大小的頁面,超過佈局大小的頁面會出現滾動條,視覺視圖則是整個文檔的大小。當佈局視圖容許的頁面最大尺寸等於手機屏幕時,網站頁面在移動端展現的理想大小即理想視圖(設備尺寸)。瀏覽器

Meta viewport

佈局視圖等於理想視圖(設備尺寸),視覺視圖等於佈局視圖,不會出現滾動條,用戶處於最佳的狀態。bash

<meta name="viewport" content="width=device-width;initial-scale=1;maximum-scale=1; minimum-scale=1; user-scalable=no;">
複製代碼
  • device-width等於理想視口的寬度,設置width=device-width讓佈局視口等於理想視口。
  • initial-scale = 理想視口寬度/視覺視口寬度,設置initial-scale=1讓視覺視口等於理想視口,initial-scale>1頁面縮小,initial-scale<1頁面放大。

物理像素、邏輯像素、像素比

  • 物理像素(設備像素):和設備相關,分辨率越高,像素點越多,像素越高。
  • 邏輯像素(設備獨立像素):和設備無關,用來描述佈局,通常爲屏幕大小。
  • 像素比(設備像素比):簡稱爲dpr,其定義了物理像素和設備獨立像素的對應關係,它決定了一個css像素點是由多少個像素設備像素點來描繪。
型號 iPhone5 iPhone6 iPhone8Plus
邏輯像素 568x320 667x375 736x414
物理像素 1136x640 1334x750 2208x1242
屏幕倍率 @2 @2 @3
dpr 2 2 3

視口和像素

  • 理想視口:分辨率,iPhone6的分辨率 375 * 667,,@2x(Retina)
  • 視覺視口:物理屏幕的可視區域,iPhone6的物理像素 750 * 1334

理想視口的狀況下,佈局視口大小(設計稿尺寸)邏輯尺寸大小,可是在高清屏幕下,手機會根據dpr對其進行轉化,致使CSS中的1px其實對應的兩倍屏2px,三倍屏的3px,爲了解決這個問題,能夠將佈局視口 = 邏輯尺寸 * dpr 讓高清屏全屏顯示大尺寸;或者放大頁面app

1px解決方案

  • IOS解決方案
.border { border: 1px solid #999 }
@media screen and (-webkit-min-device-pixel-ratio: 2) {
    .border { border: 0.5px solid #999 }
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
    .border { border: 0.333333px solid #999 }
}
複製代碼
  • :before&:after&transform(兼容)
.radius-border{
    position: relative;
}
@media screen and (-webkit-min-device-pixel-ratio: 2){
    .radius-border:before{
        content: "";
        pointer-events: none; /* 防止點擊觸發 */
        box-sizing: border-box;
        position: absolute;
        width: 200%;
        height: 200%;
        left: 0;
        top: 0;
        border-radius: 8px;
        border:1px solid #999;
        -webkit-transform(scale(0.5));
        -webkit-transform-origin: 0 0;
        transform(scale(0.5));
        transform-origin: 0 0;
    }
}
複製代碼
  • viewport縮放
//dpr爲2時,安卓下經過flexible.js動態設置無效,initial-scale=0.5始終默認爲1
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
複製代碼

移動端適配方案

  • 利用viewport進行採用理想視口
  • 利用rem調整不一樣設備之間的邏輯尺寸不一致的問題
  1. 使用理想視口,固定高度,寬度自適應:
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
複製代碼

垂直方向使用固定的值,水平方向使用彈性佈局,元素採用定值、百分比、flex佈局等。這種方案相對簡單,還原設計稿程度較低,尺寸通常都採用百分比和固定值,不能跟隨設備變化而調整,高清屏的設計稿尺寸要縮小1/2或1/3。iphone

  1. 根據不一樣屏幕動態寫入font-size,以rem做爲寬度單位。
// 屏幕的佈局視口寬度(理想視口) 
var width = document.documentElement.clientWidth;
//750px設計稿將佈局視口分爲7.5份
var rem = width / 7.5;
//1rem等於設計稿上的100px
rem = px * 0.01;    

在ipone6上: 
width = document.documentElement.clientWidth    //375px;
rem = 375px / 7.5                               //50px; 
0.75rem = 37.5px;  
在任意其餘機型上:
width = document.documentElement.clientWidth    //420px;
rem = (375px / 7.5)*(420/375)                   //56px; 
0.75rem = 42px
複製代碼

利用rem來消除高清屏倍率的問題,利用rem調整不一樣設備之間的邏輯尺寸不一致的問題,利用百分比還原設計圖,可是沒法消除1px的影響ide

  1. 以rem做爲寬度單位,利用縮放比例消除1px影響。
// 屏幕的佈局視口寬度
var width = document.documentElement.clientWidth;
// 將佈局視口分爲10份
var rem = width / 10;                               

var devicePixelRatio = window.devicePixelRatio;
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
var dpr,scale; 
if (isIPhone) { 
    if (devicePixelRatio >=3) { 
    dpr = 3; 
    } else if (devicePixelRatio >=2) { 
    dpr = 2; 
    } else { 
    dpr = 1; 
    } 
} else { 
    dpr = 1; 
} 
scale = 1 / dpr; 

在ipone6上: 
width = document.documentElement.clientWidth    //750px;
rem = 750px / 10                                //75px; 
1rem = 75px; 
在任意其餘機型上:
width = document.documentElement.clientWidth    //840px;
rem = (840px / 10)*(420/375)                    //94.08px; 
1rem = 94.08px   
複製代碼

利用viewport進行縮放來消除高清屏倍率的問題,能消除1px的問題,利用rem調整不一樣設備之間的邏輯尺寸不一致的問題,利用百分比還原設計圖,可是其1rem等於75px或者其餘不固定尺寸不方便計算。佈局

  1. vw和viewport放縮
var devicePixelRatio = window.devicePixelRatio;
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
var dpr,scale; 
if (isIPhone) { 
    if (devicePixelRatio >=3) { 
    dpr = 3; 
    } else if (devicePixelRatio >=2) { 
    dpr = 2; 
    } else { 
    dpr = 1; 
    } 
} else { 
    dpr = 1; 
} 
scale = 1 / dpr; 

100vw = 100%width 
複製代碼

使用放縮消除1px的影響,用vw來替代了rem,將rem解放出來,因此rem用來設置字體的大小,在移動端能夠兼容用戶設置字體大小的影響。字體

  1. 根據不一樣屏幕動態寫入font-size和viewport,以rem做爲寬度單位。爲了消除這種不利的影響將上面進行修改:
// 屏幕的佈局視口寬度
var width = document.documentElement.clientWidth;   
//750px設計稿將佈局視口分爲7.5份
var rem = width / 7.5;
//1rem等於設計稿上的100px
rem = px * 0.01;                

var devicePixelRatio = window.devicePixelRatio;
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
var dpr,scale; 
if (isIPhone) { 
    if (devicePixelRatio >=3) { 
    dpr = 3; 
    } else if (devicePixelRatio >=2) { 
    dpr = 2; 
    } else { 
    dpr = 1; 
    } 
} else { 
    dpr = 1; 
} 
scale = 1 / dpr; 

在ipone6上: 
width = document.documentElement.clientWidth    //750px;
rem = 750px / 7.5                               //100px; 
0.75rem = 75px; 
在任意其餘機型上:
width = document.documentElement.clientWidth    //840px;
rem = 56px; 
0.75rem = 84px  
複製代碼

利用viewport進行縮放來消除高清屏倍率的問題,能消除1px的問題,利用rem調整不一樣設備之間的邏輯尺寸不一致的問題,利用百分比還原設計圖,方便計算。flex

結語

終於揭開了移動端佈局的面紗,錯誤的地方望指正。

相關文章
相關標籤/搜索