移動端自適應布局方案嘗試

qzbs0963 8年前發布 | 6K 次閱讀 移動設計 移動開發

問題

剛開始接觸移動端H5頁面的時候最困擾的幾個問題是:

  1. 6或6p上明明是1px的邊框怎么就成了2px或3px辣么粗!
  2. 圖片,div等如何等比自適應設計圖

后來慢慢知道了第一點是由于retina屏幕下設備像素比的問題造成,第二點知道了單位rem。

目的

不想因為使用rem而一一去計算設計稿的尺寸,設計稿750的尺寸的標注可以直接在sass中使用;字體不使用rem縮放,原因是:

顯然,我們在iPhone3G和iPhone4的Retina屏下面,希望看到的文本字號是相同的。也就是說,我們不希望文本在Retina屏幕下變小,另外,我們希望在大屏手機上看到更多文本,以及,現在絕大多數的字體文件都自帶一些點陣尺寸,通常是16px和24px,所以我們不希望出現13px和15px這樣的奇葩尺寸。

還一個目的是,在頁面沒有設置viewport的時候動態設置,并且不讓頁面有一個“閃現”的過程(也就是剛加載沒設置的狀態到設置的狀態);頁面動態變化時,尺寸相應變化;

嘗試

在寫H5頁面的時候,盡可能少的去寫meta標簽,我會這樣做:

<head>
    <title>viewport test</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style/style.css">
</head>

就這樣簡單,然后實現的代碼當然是放在head里。因為并沒有寫viewport,所以得判斷加上

if (!metaEl) {
    metaEl = doc.createElement('meta');
    metaEl.setAttribute('name', 'viewport');
    metaEl.setAttribute('content', 'width=device-width,initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no');
    if (docEl.firstElementChild) {
        docEl.firstElementChild.appendChild(metaEl);
    } else {
        var wrap = doc.createElement('div');
        wrap.appendChild(metaEl);
        doc.write(wrap.innerHTML);
    }
}

然后根據頁面的devicePixelRatio縮放

var scale = parseFloat((1 / dpr).toFixed(2));
if (dpr != 1) {
    metaEl.setAttribute('content', 'width=device-width,initial-scale='+ scale +', maximum-scale='+ scale +', minimum-scale='+ scale +', user-scalable=no');
}

設置根字體大小

// document width
function setDocumentFontSize () {
    var width = docEl.getBoundingClientRect().width;
    docEl.style.fontSize = width / 10 + 'px';
}
setDocumentFontSize();

頁面resize監聽

var timer;
win.addEventListener('resize', function() {
    clearTimeout(timer);
    timer = setTimeout(function () {
        setDocumentFontSize();
    }, 300);
}, false);

為了字體不使用rem,需要為documentElement設置data-dpr屬性

// document data-dpr set font-size px
var dpr = window.devicePixelRatio;
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
    dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
    dpr = 2;
} else {
    dpr = 1;
}
docEl.setAttribute('data-dpr', dpr);

sass相關設置

完全根據設計稿尺寸寫

// baseFontSize 
$baseFontSize: 75;
@function px2rem($px){
    @return $px/$baseFontSize * 1rem;
}
@function px2rem2($px){
    @return px2rem($px*2);
}

字體大小變化

// 字體大小計算
@mixin font-dpr($font-size){
    font-size: $font-size;

[data-dpr="2"] & {
    font-size: $font-size * 2;
}

[data-dpr="3"] & {
    font-size: $font-size * 3;
}

}</pre>

例如:一個簡單樣式的設置

.test {
    @include font-dpr(10px);
    width: px2rem2(300);
    margin: 0 auto;
    border:1px #dcdcdc solid;
}
img {
    display: block;
    width: px2rem2(355);
    margin: 0 auto;
}

效果示例:

可以從圖中看出,6p的dpr為3,字體相應為30px,頁面縮放了3倍,正式我所想要的(圖片可以右鍵在新的窗口打開看大圖)。

頁面demo源碼

<!DOCTYPE html>
<html>
<head>
    <title>viewport test</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style/style.css">
    <script>
    ;(function (win) {
        var doc = win.document;
        var docEl = doc.documentElement;
        var metaEl = doc.querySelector('meta[name="viewport"]');

    if (!metaEl) {
        metaEl = doc.createElement('meta');
        metaEl.setAttribute('name', 'viewport');
        metaEl.setAttribute('content', 'width=device-width,initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no');
        if (docEl.firstElementChild) {
            docEl.firstElementChild.appendChild(metaEl);
        } else {
            var wrap = doc.createElement('div');
            wrap.appendChild(metaEl);
            doc.write(wrap.innerHTML);
        }
    }

    // document data-dpr set font-size px
    var dpr = window.devicePixelRatio;
    if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
        dpr = 3;
    } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
        dpr = 2;
    } else {
        dpr = 1;
    }
    docEl.setAttribute('data-dpr', dpr);

    var scale = parseFloat((1 / dpr).toFixed(2));
    if (dpr != 1) {
        metaEl.setAttribute('content', 'width=device-width,initial-scale='+ scale +', maximum-scale='+ scale +', minimum-scale='+ scale +', user-scalable=no');
    }

    // document width
    function setDocumentFontSize () {
        var width = docEl.getBoundingClientRect().width;
        docEl.style.fontSize = width / 10 + 'px';
    }
    setDocumentFontSize();

    var timer;
    win.addEventListener('resize', function() {
        clearTimeout(timer);
        timer = setTimeout(function () {
            setDocumentFontSize();
        }, 300);
    }, false);
})(window);
</script>

</head> <body>

<div class="test">
    顯然,我們在iPhone3G和iPhone4的Retina屏下面,希望看到的文本字號是相同的。也就是說,我們不希望文本在Retina屏幕下變小,另外,我們希望在大屏手機上看到更多文本,以及,現在絕大多數的字體文件都自帶一些點陣尺寸,通常是16px和24px,所以我們不希望出現13px和15px這樣的奇葩尺寸。
</div>

<img src="https://camo.githubusercontent.com/3bd9e24ee11cee86e81dc49c0e5722e9f55e7297/687474703a2f2f7777772e773363706c75732e636f6d2f73697465732f64656661756c742f66696c65732f626c6f67732f323031352f313531312f72656d2d392e6a7067" alt="">

</body> </html></pre>

 

 

來自:http://ymblog.net/2016/09/23/viewport/

 

 本文由用戶 qzbs0963 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!