1. 程式人生 > 實用技巧 >移動端的3種適配方法

移動端的3種適配方法

做移動端頁面以來,經常會聽說移動端的適配這個問題,但是並沒有認真分析過是如何適配各種機型的。目前公司用的是手淘的flexible.js進行頁面適配的。適配的根本原理其實就是將設計稿按一定的比例在不同的手機上實現。

在分析移動段適配之前首先要了解一下rem,css3的一個相對長度單位。既然是相對長度,那就有一個參照體了,rem就是相對於html元素的font-size計算值的倍數。即1rem 等於一倍的html元素的font-size值。

接下來分析一下三種移動端適配的方法

一、@media + rem

最早看到這個適配是在同事的程式碼裡,當時並不知到是什麼原理,也並不明白這些數字是怎麼來的。

@media screen and (min-width:350px){
    html{font-size:342%;}
}
@media screen and (min-width:360px){
    html{font-size:351.56%;}
}
@media screen and (min-width:375px){
    html{font-size:366.2%;}
}
@media screen and (min-width:384px){
    html{font-size:375%;}
}
@media screen and (min-width:390px){
    html{font-size:380.85%;}
}
@media screen and (min-width:393px){    /* 小米NOTE */
    html{font-size:383.79%;}
}
@media screen and (min-width:410px){
    html{font-size:400%;}
}
@media screen and (min-width:432px){ /* 魅族3 */
    html{font-size:421.875%;}
}
@media screen and (min-width:480px){
    html{font-size:469%;}
}
@media screen and (min-width:540px){
    html{font-size:527.34%;}
}
@media screen and (min-width:640px){
    html{font-size: 625%;}
}

@media screen and (width:720px){
    html{font-size: 703.125%;}
}

@media
媒體查詢, 可以針對不同的螢幕尺寸設定不同的樣式,特別是如果你需要設定設計響應式的頁面,@media 是非常有用的。當你重置瀏覽器大小的過程中,頁面也會根據瀏覽器的寬度和高度重新渲染頁面。

上述程式碼中,第一個@media screen and (min-width:350px)表示當移動裝置的寬度大於350px的時候頁面將使用花括號內的樣式,即將html根元素的字號設定為342%。(max-width:350px,則表示裝置寬度小於350px時將採用此樣式)。上述css程式碼的作用可見就是在不同解析度的裝置上設定不同的html字型大小。

為什麼要這樣設定呢?因為這種適配方法用的是css3的rem來進行適配的,而前面講了,rem是相對於html的字號來計算的,現在不同的裝置上html的字號改變了,也就意味這1rem代表的px畫素值不同了,也就達到了按比例在不同裝置上適配同一個頁面的效果了。

html元素的font-size值又是怎麼確定的呢?拿下面的舉例:

@media screen and (min-width:375px){
    html{font-size:366.2%;}
}

螢幕寬度大於375px的會按照寬度375px來適配。設計同時平時給我們的設計稿一般是640px寬度或者750px寬度的,而我們上面的都是假定設計稿是640px寬來計算的,750px也是同理計算。現在:

1.螢幕寬度是375,設計稿寬度是640,ratio = 375/640=0.5859375;
2.我們要將設計稿上元素用css單位rem寫下來,那麼該如何轉換,1rem應該等於稿子上多少px。
這裡我們設定1rem = 100px;可以設定其它值嗎,當然可以,這裡設定為100只是方便我們在寫css的時候好計算,小數點直接左移兩位就可以了。比如,設計稿上一個寬46px按鈕,這樣轉換成rem直接就是0.46rem。
3.現在1rem代表設計稿上100px,那麼又該是等於裝置上最後真實的多少畫素呢。就要用到前面的螢幕寬度和設計稿的寬度比ratio,設計稿上100px代表了真實的裝置100*ratio = 58.59375px。
換句話說 css中寫的1rem等於裝置58.59375px。又因為1rem等於1倍的html元素的font-size,所以這裡的html元素的font-size最終應該設定成58.59375px。可為什麼上述程式碼中用的是百分比呢?因為一般瀏覽器中html元素的預設字號都是16px,但是當用戶放大或者縮小瀏覽器字號設定時,就不會是16px了,所以我們將html的font-size還是設定成百分比更好,即 58.59375/16= 366.2109375%,也就是上面例子中的366.2%了。

其它的螢幕上也是同此道理計算出html的font-size值的。

@media + rem適配移動端還有一個不可少的條件就是要在head標籤中寫入一個meta標籤。<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, minimum-scale=1">;關於viewport的瞭解可以看這裡。此標籤的作用是讓layout viewport = visual viewport,使用者也不可縮放頁面。

二、手機淘寶 flexible.js

flexible.js也是rem適配的,它是將裝置分成10份,1rem等於1/10。分析其中部分程式碼:

   var devicePixelRatio = win.devicePixelRatio;

        dpr = devicePixelRatio || 1;
        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;
        
       ......
       .......
        
       metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

win.devicePixelRatio(簡稱dpr),即裝置畫素比(戳我瞭解)

上述程式碼當dpr(裝置物理畫素和裝置獨立畫素比)為3時候,頁面縮入1/3,dpr為2時,頁面綻放2/1。

   function refreshRem(){
        var width = docEl.getBoundingClientRect().width;
        if (width / dpr > 750) {
            width = 750 * dpr;
        }
        var rem = width / 10;
        docEl.style.fontSize = rem + 'px';
        flexible.rem = win.rem = rem;
    }

上述程式碼將1rem設定成了裝置真實寬度的1/10,因此html根元素的fontSize也就是裝置真實寬度的1/10,假如設計老鐵們給的漂亮稿子是750px寬的,寫scss時1rem也就應該等於75px,那邊我麼的scss檔案可以這樣寫:

@function px2rem($px, $base: 75) {
    @return ($px / $base) * 1rem;
}
/*
稿子上量得某按鈕寬60px,高20px
*/
.btn{
    width:px2rem(60);
    height:px2rem(20);
}

PPT模板下載大全https://redbox.wode007.com

三、vw,vh進行適配

vw:viewport width(可視視窗寬度)
vh:viewport height(可視視窗高度)
vw和vh等詳情可以點這裡
1vw等於1%的裝置寬度(設計稿寬度),1vh等於1%的裝置高度(設計稿高度),這樣看來vw,vh其它是最方便的,但是目前相容性不是特別好。

所以只有在不需要考慮相容的時候可以用這個相對最簡便的適配方案了,比如一些混合開發裡,app內的瀏覽器如果支援vw、vh,只在app內使用的頁面就可以放心大膽的用了。像下面的

客戶端內的右下角webview,一個小的PK對決頁面,這裡就是用的vw,vh進行適配的。

/*右下角視窗設計稿寬200px,高220px*/
@function px2vw($px, $base: 200) {
  @return ($px/($base/100)) + vw;
}
@function px2vh($px, $base: 220) {
  @return ($px/($base/100)) + vh;
}
/*頭像寬42px,高42px*/
.avantar{
    width:px2vw(42);
    heightx:px2vh(42);
}

目前工作中用到的就是後面的兩種適配方案了。手淘那個還有的地方看不懂,還是自己太Low了,但是看不懂車不影響老司機開車。