直接採用媒體查詢加百分比去佈局。javascript
核心思想:css
頁面主體佈局基本採用百分比去設置。html
而後,其餘塊內佈局,例如font-size
等可經過設置媒體查詢的斷點來分設置,已達到兼容其餘手機尺寸。java
優勢:android
靈活,簡單ios
兼容性好,媒體查詢,97.65%的瀏覽器都支持了。git
缺點:github
媒體查詢的斷點設置麻煩,只能在選取的幾個主流設備尺寸下呈現完美適配。瀏覽器
1px的問題,須要額外作處理,好比transform:scaleX(0.5)
。app
例子:京東
這個方案比較簡單和實用,理解起來也不難。
原理:
自動經過hotcss.js計算頁面的html
的font-size
的大小,其後在佈局中使用rem做爲像素單位,使得頁面在不一樣的移動設備上能夠視覺一致。
經過獲取dpr,在html
上設置屬性data-dpr
,在設置font-size
時,能夠配合data-dpr
來使用px做爲像素單位。
計算scale,爲頁面設置viewport
,使得頁面根據dpr進行縮放,最終達到,1個物理像素=1px。這樣,也有效解決了1px的問題。
默認在320px屏幕中(非Retina屏),1rem=20px;
核心源碼:
計算dpr並設置data-dpr
和scale
//計算dpr var dpr=window.devicePixelRatio||1; //在其餘的一些方案中,會區分ios和android,對android統一設置爲1. dpr=dpr>=3?3:(dpr>=2?2:1); //設置data-dpr document.documentElement.setAttribute('data-dpr',dpr); //計算scale var scale=1/dpr, content='width=device-width,initial-scale='+scale+',minimum-scale='+scale+',maximum-scale='+scale+',user-scalable=no'; //插入meta,設置頁面縮放 var viewport=document.createElement('meta'); viewport.setAttribute('name','viewport'); viewport.setAttribute('content',content); document.head.appendChild(viewport);
計算font-size
並設置html
的font-size
//獲取設備的寬度 var innerWidth=document.documentElement.getBoundingClientRect().width||window.innerWidth; //計算font-seize,默認320px中,1rem=20px. document.documentElement.style.fontSize=(innerWidth*20/320)+'px';
優勢:
後續佈局處理簡單,配合px2rem插件等,使用十分方便。
基本能很好適配市面即大多數尺寸手機。
兼容性也比較好,97.62%瀏覽器基本支持rem單位了。
經過設置縮放比例,有效解決了1px的問題。
缺點:
頁面須要額外引入js腳本去計算,增長一次額外的http請求,或內嵌到頁面中增長頁面體積大小。
例子:卷皮
這個是手機淘寶推出來一個方案,解決手機淘寶H5在移動端的佈局。
原理:
自動經過flexible.js計算頁面html
的font-size
的大小,而後在頁面佈局中使用rem做爲單位,而非px。
若是頁面指定了meta[name="viewport"]
,則直接根據已有的meta標籤來設置縮放比例;不然,經過dpr
來自動計算頁面縮放比例。
設置1rem=10vw,例如,在320px屏幕(非Retina屏),1rem=32px;
核心源碼:
計算縮放比例
//參試獲取頁面已定義的縮放比例 var metaEl = doc.querySelector('meta[name="viewport"]'); if(metaEl){ console.warn('將根據已有的meta標籤來設置縮放比例'); var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/); if (match) { scale = parseFloat(match[1]); dpr = parseInt(1 / scale); } } //若是沒有,則自動計算 if (!dpr && !scale) { var isAndroid = win.navigator.appVersion.match(/android/gi); var isIPhone = win.navigator.appVersion.match(/iphone/gi); var devicePixelRatio = win.devicePixelRatio; 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; }
設置meta
if (!metaEl) { metaEl = doc.createElement('meta'); metaEl.setAttribute('name', 'viewport'); metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); if (docEl.firstElementChild) { docEl.firstElementChild.appendChild(metaEl); } else { var wrap = doc.createElement('div'); wrap.appendChild(metaEl); doc.write(wrap.innerHTML); } }
計算頁面的html的font-size
var width = docEl.getBoundingClientRect().width; //最大屏幕寬度爲540*dpr if (width / dpr > 540) { width = 540 * dpr; } //設置1rem=10vw var rem = width / 10; docEl.style.fontSize = rem + 'px'; flexible.rem = win.rem = rem;
優缺點同hotcss。
例子:淘寶
這種方案就是在計算html的font-size時,是根據vw去自動計算,而不是用js腳本去動態計算。vw是一種新的單位,相似的還有vh,vmin,vmax。定義以下:
vw:1vw等於視口寬度的1%;例如,320px寬度視口中,1vw=3.2px,10vw=32px,100vw=320px;
vh:1vh等於視口高度的1%;例如,568px高度視口中,1vh=5.58px,10vh=56.8px,100vh=568px;
vmin:選取vw和vh中最小的那個;
vmax:選取vw和vh中最大的那個;
核心思想:
不用js去動態計算頁面的font-size ,而是設置根元素html的font-size=?vw;這裏的?,能夠選取一種屏幕尺寸去參考計算。例如,咱們想iPhone6下,html的font-size爲100px。那個html的font-size=100/375=0.26666666666666666vw。那麼,其餘屏幕的適配計算方式就是:
iphone5:屏幕是320*568 html的font-size=0.26666666666666666*320=85.33333333333333 iphone6s:屏幕是414*736 html的font-size=0.26666666666666666*414=110.39999999999999
頁面佈局採用rem佈局,而非px。根據html的font-size和rem單位自動計算出了佈局px。
優勢:
不須要額外引入js腳本去計算,自動根據vw去計算font-size
後續佈局也超級簡單,採用rem便可。
缺點:
vw單位的支持相對比rem的瀏覽器少一些,目前有93.65%的瀏覽器都支持了。
例子:拼多多