移動(dòng)端布局闲礼,為了適配各種大屏手機(jī)贮缅,目前最好的方案莫過于使用相對(duì)單位 ?rem.
基于rem的原理唇聘,我們要做的就是針對(duì)不同手機(jī)屏幕尺寸,和dpr動(dòng)態(tài)的修改根節(jié)點(diǎn)HTML的font-size的大刑志隆(基準(zhǔn)值)脂信。
這里我們提取一個(gè)計(jì)算rem的公式:
rem = document.documentElement.clientWidth * dpr / 10癣蟋;
說明:
1. 乘以dpr ,是因?yàn)轫?yè)面有可能為了實(shí)現(xiàn) 1px border 頁(yè)面會(huì)縮放(scale)1/ dpr 倍(如果沒有狰闪,dpr=1)疯搅。
2. 除以 10 ,這純粹是為了取整埋泵,方便計(jì)算幔欧,這個(gè)值可以是任何值,根據(jù)個(gè)人喜好定丽声。
所以就像礁蔗,下面這樣,HTML的font-size可能會(huì)是:
iPhone 3 : 320px / 10 = 32px;
iPhone 4/5 :320px * 2 / 10 = 64px;
iPhone 6 : ? 375px * 2 / 10 = 75px;
對(duì)于動(dòng)態(tài)改變根節(jié)點(diǎn)的font-size雁社,我們可以通過css做浴井,也可以通過JavaScript做。
css方式歧胁,可以通過設(shè)備寬度來媒體查詢改變HTML的font-size:
html { font-size : 32px; }
//iphone 6
@media( min-device-width : 375px ){
? ? ? ? ? ? ? html{ font-size : 64px; }
}
// iphone6 plus
@media( min-device-width : 414px ){
? ? ? ? ? html{ font-size : 75px; }
}
缺點(diǎn):通過設(shè)備寬度 ”范圍查詢“ 滋饲,這樣的媒體查詢來動(dòng)態(tài)改變r(jià)em基準(zhǔn)值,其實(shí)不夠精確喊巍,比如:寬度為360px和寬度320px的手機(jī)屠缭,因?yàn)槠翆捲谕粋€(gè)范圍區(qū)間內(nèi)(<375px),所以會(huì)被等同對(duì)待(rem基準(zhǔn)值相同),而事實(shí)上他們的屏幕寬度并不相等崭参,他們的布局也應(yīng)該有所不同呵曹。最終結(jié)論就是:這樣的做法,沒有做到足夠的精確何暮,但是夠用奄喂。
JavaScript方式,通過上面的公式海洼,計(jì)算出基準(zhǔn)值rem跨新,然后寫入樣式
var ?dpr , rem , scale;
var docEl = document.documentElement;
var fontEl = document.createElement("style");
var metaEl = document.querySelector("mate[name = 'viewport']");
dpr = window.devicePixelRatio || 1;
rem = docEl.clientWidth * dpr / 10;
scale = 1 / dpr;
// 設(shè)置viewport ,進(jìn)行縮放坏逢,達(dá)到高清的效果域帐;
metaEl.setAttribute('content','width=', + dpr * docEl.clientWidth + ',initial-scale='+scale+',maximum-scale='+scale+', minimum-scale='+scale+',user-scalable=no');
//設(shè)置data-dpr屬性,留作css hack之用
docEl.setAttribute('data-dpr',dpr);
//動(dòng)態(tài)寫入樣式
docEl.firstElementChild.appendChild(fontEl);
fontEl.innerHTML = 'html{font-size:' + rem + 'px !importment; }';
//給js調(diào)用的是整,某一dpr下rem和px之間的轉(zhuǎn)換函數(shù)
window.rem2px = function ( v ) {
? ? ? ?v = parseFloat ( v );
? ? ? ?return v * rem;
};
window.px2rem = function ( v ){
? ? ? ? v = parseFloat( v );
? ? ? ? return ?v / rem;
}
window.dpr = dpr;
window.rem = rem;
這種方式可以精確的計(jì)算出不同屏幕所對(duì)應(yīng)的rem基準(zhǔn)值肖揣,缺點(diǎn)就是要加載一段js代碼,但是個(gè)人覺得這是目前最好的解決方式浮入。
因?yàn)檫@個(gè)方案同時(shí)解決了三個(gè)問題:
1. 1px border 的問題龙优。
2. 圖片高清問題。
3. 屏幕適配布局問題事秀。
字體大小問題
既然上面的方案會(huì)使得頁(yè)面縮放(scale)彤断,對(duì)于頁(yè)面區(qū)域的寬高野舶,我們可以依賴高清視覺稿,因?yàn)橐曈X稿本來就是x2的瓦糟,我們直接量就可以了筒愚,那么對(duì)于字體該如何處理那?
對(duì)于字體的縮放問題菩浙,設(shè)計(jì)師原本的要求是在任何手機(jī)屏幕上字體大小都要統(tǒng)一巢掺,所以我們針對(duì)不同的dpr直接使用px就可以了。
font-size : 16px;
[ data-dpr = '2' ] input {
? ? ? ?font-size : 32px;
}
字體不可以使用rem劲蜻,誤差太大陆淀,且不能滿足任何屏幕下文字大小相同。
手淘手機(jī)適配參考文章:http://blog.csdn.net/liujie19901217/article/details/51982403