h5的移動端適配核心的問題有兩個:
1.因為目前手機品牌眾多,手機的寬度不統一,所以第一個問題就是如何讓不同的手機顯示的內容看起來是一樣的?
2.因為目前市場上的手機多數是高清屏,如何解決高清的問題?
這篇文章將會介紹rem是如何解決這兩個問題。
一、rem的簡介
rem是css3新增的屬性,是一個相對單位(相對根節點html的字體大小來計算)。比如:html的font-size為64px,2rem則是128px。
二、rem方案
這個方案本質上是寬度等比適配,不同的手機通過動態的計算出html的字體大小來做等比換算,讓視覺(拿一部分出來,比如正方形)占手機寬度的比例在不同手機上是相等的,這樣就可以在不同手機上看起來是一個樣子。
動態計算html的字體大小的公式如下:
rem = document.documentElement.clientWidth * dpr / 10
說明:
1.乘以dpr,是因為頁面有可能為了實現1px border頁面會縮放(scale) 1/dpr 倍(如果沒有,dpr=1)。
2.除以10,是為了取整,方便計算(理論上可以是任何值)。
3.根據這個公式可以知道,手機的clientWidth(屏幕寬度)和dpr(物理像素 / 設備獨立像素)決定了html的字體大小(基準值)。比如:
iphone3gs: 320px / 10 = 32px
iphone4/5: 320px * 2 / 10 = 64px
iphone6: 375px * 2 / 10 = 75px
這樣子假如一個針對iphone6的高清視覺稿 750×1334,如果有一個區塊,在psd文件中量出:寬高750×300px的div(寬度占滿屏幕),那么轉換成rem單位(rem = px / 基準值):寬高為10x4rem。這樣的rem在iPhone4中換算成px為640x256px(寬度也是占滿屏幕的)。
三、代碼實現
這個方案只需要在加載頁面的body的時候先執行以下js代碼就可以做到適配的效果。
var dpr, rem, scale;
var docEl = document.documentElement;
var fontEl = document.createElement('style');
var metaEl = document.querySelector('meta[name="viewport"]');
dpr = window.devicePixelRatio || 1;
rem = docEl.clientWidth * dpr / 10;//基準值
scale = 1 / dpr;
// 設置viewport,進行縮放,達到高清效果
//理論上,1個位圖像素對應于1個物理像素,圖片才能得到完美清晰的展示。
metaEl.setAttribute('content', 'width=' + dpr * docEl.clientWidth + ',initial-scale=' + scale+ ',maximum-scale=' + scale + ', minimum-scale=' + scale + ',user-scalable=no');
// 動態寫入樣式
docEl.firstElementChild.appendChild(fontEl);
fontEl.innerHTML = 'html{font-size:' + rem + 'px!important;}';