原文地址:移動端自適應佈局方案嘗試css
問題html
剛開始接觸移動端H5頁面的時候最困擾的幾個問題是:git
後來慢慢知道了第一點是因爲retina屏幕下設備像素比的問題形成,第二點知道了單位rem。github
目的sass
不想由於使用rem而一一去計算設計稿的尺寸,設計稿750的尺寸的標註能夠直接在sass中使用;字體不使用rem縮放,緣由是:app
顯然,咱們在iPhone3G和iPhone4的Retina屏下面,但願看到的文本字號是相同的。也就是說,咱們不但願文本在Retina屏幕下變小,另外,咱們但願在大屏手機上看到更多文本,以及,如今絕大多數的字體文件都自帶一些點陣尺寸,一般是16px和24px,因此咱們不但願出現13px和15px這樣的奇葩尺寸。佈局
還一個目的是,在頁面沒有設置viewport的時候動態設置,而且不讓頁面有一個「閃現」的過程(也就是剛加載沒設置的狀態到設置的狀態);頁面動態變化時,尺寸相應變化;字體
嘗試spa
在寫H5頁面的時候,儘量少的去寫meta標籤,我會這樣作:.net
<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; } }
例如:一個簡單樣式的設置,(在這裏設計稿給的尺寸是300*auto,邊框是1px)
.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倍,同時,1px邊框在設備像素密度爲3倍的狀況下依舊顯示的1px(由於被縮小了),正是我所想要的。
頁面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>
歡迎關注個人博客:http://ymblog.net