移動端的開發基本不多直接使用px做爲單位了,目前最經常使用的是rem。不過在這以前其實還有個em單位,和rem長得很是的像,那麼它們有什麼區別呢?又有什麼不同的適用場景呢?javascript
注意:不管使用em,仍是rem,客戶端最終解析的值依舊是px!
從title的解釋就能夠看出,em的基準是其父級元素,不過這個父級元素要求是設置有font-size值的,以下面的例子:css
<div class="father" style="font-size:20px;"> <div class="son" style="font-size:2em;"></div> </div>
那麼son的字體大小就是2 * 20px = 40px,此時,若是father的字體大小變化了,那麼son的也會跟着變化。假如沒有父元素,則基準就是body(因爲默認瀏覽器默認字體爲16px,因此默認狀況1em=16px)。html
跟上面解釋body基準時的差很少,默認狀況下1rem=16px。此時,只要根元素字體大小不變,那麼相對於它的rem就不會變。
對於移動端的各類機型來說,因爲不一樣的機型屏幕尺寸、分辨率都不同,不太可能使用相同的根元素字體大小做爲基準,因此所謂rem佈局,就是經過js動態計算出不一樣機型的根元素字體大小值,來對頁面進行等比例的縮放,達到適配大部分機型的效果。
那麼具體如何去設定這個基準呢?
假設把手機屏幕寬度均分紅10等份(由於rem佈局就是針對寬度去作設定的),規定其中的一份做爲根元素的font-size值,那麼根元素font-size值就可由下述公式得到:前端
document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';
在這個基準下,那麼1rem的值也隨之獲得了:java
1rem = document.documentElementstyle..fontSize = document.documentElement.clientWidth / 10 + 'px';
那麼,不一樣屏幕的機型因爲屏幕寬度不一樣,也就獲得了在"屏幕寬度均分紅10等份"這個標準下的rem相對值。比較完整的計算方式以下:git
// set 1rem = viewWidth / 10 function setRemUnit () { var rem = docEl.clientWidth / 10 docEl.style.fontSize = rem + 'px' } setRemUnit() // reset rem unit on page resize window.addEventListener('resize', setRemUnit) window.addEventListener('pageshow', function (e) { if (e.persisted) { setRemUnit() } })
注意:這裏的標準 "10"能夠是任一值,只要跟下面轉換公式中用到的標準值保持一致便可,這裏只是爲了計算方便才這麼設定。
這樣,rem的基礎生態就搭建好了。那麼如何基於這套標準應用到開發中去呢?github
在繼續以前,先來了解下"像素"這個知識點,由於接下來都會用到它的概念。
像素分爲兩種:設備像素和CSS像素
一、設備像素(device independent pixels): 設備屏幕的物理像素,任何設備的物理像素的數量都是固定的
二、CSS像素(CSS pixels): 又稱爲邏輯像素,是爲web開發者創造的,在CSS和javascript中使用的一個抽象的層
在pc端,css像素和物理像素是1:1的關係;而在移動端,因爲相似retina的各類高清屏的出現,css像素和物理像素的關係通常是1:2或者1:3,即1個css像素容納2到3個物理像素,實現高清的效果。
通常移動端頁面的開發流程是:設計人員以某個機型做爲標準,設計好UI。前端開發針對這個機型的UI作開發,而後其它機型相對的去等比例縮放。
這裏以iphone6做爲標準(由於實際開發中基本也是用它作設計),它的物理像素爲750x1334,css像素爲375*667,假設UI上圖片a的寬度爲140,那麼如何把它轉換成以rem爲單位的值呢?
如今屏幕寬度是已知的10rem,要求UI上寬140的rem值,假設爲X,由下圖能夠很容易的獲得比例關係:web
屏幕寬度/UI寬度 = x/140 = 10rem / 750 =》 x = 140 / 750 * 10 rem
通常能夠在sass中經過封裝預處理函數進行這個轉換過程:編程
$UI_WIDTH: 750; @function px2rem($px) { @return ${ $px / $UI_WIDTH * 10 }rem; //=>or @return ${ $px / 75 }rem; } img{ width: px2rem(140); }
這就是"rem佈局"原理的整個實現過程!瀏覽器
而隨着社區各類工具的完善,如今也無需手動去使用如px2rem的這種預處理函數去轉換,比較流行的作法是使用postcss的postcss-px2rem插件去自動處理,開發時仍然按照px的方式去編程,postcss配置例:
postcss: function() { return [px2rem({remUnit: 75})]; //設置基準值,75是以iphone6的標準 }
這裏的remUnit設置是有必定規則的,好比屏幕寬度等分紅10份,當UI以iphone6(即物理像素寬度750)設計時,remUnit=75;當UI以iphone5(即物理像素寬度640)設計時,remUnit=64。能夠看出它中遵循以下公式:
remUnit = 物理像素寬度 / 設定的屏幕寬度等分值;
至於具體的js等分邏輯封裝能夠參看手淘的flexible。
那麼在實際開發中,究竟適用em仍是rem呢?記住以下原則便可:
本文收錄在我的的Github上 https://github.com/kekobin/bl... ,以爲有幫助的,歡迎start哈。支持原創,未經本人贊成,請勿轉載!