前端開發之移動端自適應布局


大家在做移動端開發的時候如果只用px+百分比的布局方式而不做任何自適應處理的話就會出現這種情況:按照750px設計圖寫頁面,如果設計圖給的字體大小是28px一般情況下會除以2(這一步已經錯了),寫完以后放到iphone6s和iphone5測試就會發現本來在6s上感覺蠻好的到了5上就變大了。然后心中萬馬奔騰……

現在,給大家分享兩種常用的解決方案

  • 1、通過動態設置 viewport的 width 和 initial-scale

  • 2、通過動態設置跟元素Html的font-size 即 rem解決方案

1、meta viewport

meta標簽大家都很熟悉了,首先來看一下meta viewport 的6個屬性:

屬性名 解釋
width 設置viewport 的寬度,為一個正整數,或字符串"width-device"
initial-scale 設置頁面的初始縮放值,為一個數字,可以帶小數
minimum-scale 允許用戶的最小縮放值,為一個數字,可以帶小數
maximum-scale 允許用戶的最大縮放值,為一個數字,可以帶小數
height 設置viewport 的高度,這個屬性並不重要,很少使用
user-scalable 是否允許用戶進行縮放,值為"no"或"yes", no 代表不允許,yes代表允許

一般情況下width的值設置為width-device即可,即當前設備的屏幕寬度,我們可以通過window.screen.width獲取。所以要想在不同手機上自適應,我們就要動態的改變initial-scale(初始縮放值),並且設置user-scalable=no禁止用戶手動縮放頁面。

舉一個例子:如果設計師給的尺寸是750px的,如何把750px的設計圖等比縮放到我們當前寬度的手機上呢?假如當前手機的屏幕寬度是恰好是750px,那initial-scale就等於1好了完全不用縮放。假如當前的手機寬度是375px(iphone6/7/8),那豈不是要縮放一倍了(initial-scale=0.5),對的,縮放的倍數就等於當前手機屏幕寬度除以設計圖的寬度。如果設計師給的是640px寬的圖,針對不同的手機initial-scale的值是多少呢?(答案就在上一句)。

所以initial-scale的值是要動態獲取的然后將meta標簽添加到header標簽里面,這就要用js操作dom了(js基礎知識)。見下代碼示例:

<script>
    var _vwidth = window.screen.width;
    var _scale = _vwidth / 750;
    var _meta = document.createElement('meta');
    _meta.setAttribute('name', 'viewport');
    _meta.setAttribute('content', ' width = device - width , user - scalable = no , initial - scale = ' + _scale);
    document.getElementsByTagName('head')[0].appendChild(_meta);
</script>

 

之后就可以根據設計圖給的尺寸大小寫css了,是28px我們就寫28像素,寬度是750px我們就寫750px(當然:也可以寫100%)。

2、rem布局

rem是指相對於根元素的字體大小的單位,它就是一個相對單位。看到rem大家一定會想起em單位,em是指相對於父元素的字體大小的單位。一個計算的規則是依賴根元素一個是依賴父元素計算。rem自適應原理就是動態改變根元素html的font-size大小。如果設置了html{font-size:20px;},那么1rem=20px。如何動態改變html的fontSize呢,有兩種方式可以實現。第一種是通過css3的媒體查詢,這樣的話在做開發前就要先統計有哪些主流的屏幕設備,然后去針對這些設備去做不同的兼容,如下示例:

html {
    font - size:

        20px;
}

@media only screen and (min - width: 375px) {
    html {
        font - size:

            25px ! important;

    }
}

@media only screen and (min - width: 428px) {
    html {
        font - size:

            26.75px ! important;

    }
}

@media only screen and (min - width: 481px) {
    html {
        font - size:

            30px ! important;


    }
}

@media only screen and (min - width: 569px) {
    html {
        font - size:

            35px ! important;


    }
}

@media only screen and (min - width: 641px) {
    html {
        font - size:

            40px ! important;


    }
}

 

到這里肯定有很多人會疑問是怎么計算出不同分辨率下font-size的值的?其實這只是一個參考,如果設計圖尺寸是750,你可以將750對應的fontSize設置為100px,375對應fontSize就是50px以此類推。之所以在媒體查詢上面設置一個font-size : 20px;是因為當設備寬度小於375的時候都采用1rem=20px,當然這個值可以更改的。如下示例:

html {
    font - size:

        20px;
}

@media only screen and (min - width: 750px) {
    html {
        font - size:

            100px ! important;


    }
}

@media only screen and (min - width: 375px) {
    html {
        font - size:

            50px ! important;


    }
}

 

用css的方法是不能做全適配的,因為可能我們沒有統計全或者未來還會出現更多不同分辨率的手機,但是用JS是可以實現全適配。以下是通過js實現自適應,此時是針對750像素設計圖1rem=100px,即設計圖中字體大小為28像素時,我們要設置為0.28rem。還是很好換算的。如果設計圖給的是640px,只需要將結尾處的參數改成640,640即可。

(function(designWidth, maxWidth) {
    var doc = document,
        win = window,
        docEl = doc.documentElement,
        remStyle = document.createElement("style"),
        tid;

    function refreshRem() {
        var width = docEl.getBoundingClientRect().width;
        maxWidth = maxWidth || 540;
        width > maxWidth && (width = maxWidth);
        var rem = width * 100 / designWidth;
        remStyle.innerHTML = "html{font-size:" + rem + "px;}"
    }
    if (docEl.firstElementChild) {
        docEl.firstElementChild.appendChild(remStyle)
    } else {
        var wrap = doc.createElement("div");
        wrap.appendChild(remStyle);
        doc.write(wrap.innerHTML);
        wrap = null
    }
    refreshRem();
    win.addEventListener("resize", function() {
        clearTimeout(tid);
        tid = setTimeout(refreshRem, 300)
    }, false);
    win.addEventListener("pageshow", function(e) {
        if (e.persisted) {
            clearTimeout(tid);
            tid = setTimeout(refreshRem, 300)
        }
    }, false);
    if (doc.readyState === "complete") {
        doc.body.style.fontSize = "16px"
    } else {
        doc.addEventListener("DOMContentLoaded", function(e) {
            doc.body.style.fontSize = "16px"
        }, false)
    }
})(750, 750);

 

在項目中大家可根據實際情況選擇,祝大家開發順利少加班!!!

 

歡迎掃描下方二維碼關注,這里更多前端技術分享,讓我們一起成長 -- web前端周刊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM