提到rem,你們首先會想到的是em,px,pt這類的詞語,大多數人眼中這些單位是用於設置字體的大小的,沒錯這的確是用來設置字體大小的,可是對於rem來講它能夠用來作移動端的響應式適配哦。javascript
兼容性css
先看看兼容性,關於移動端html
大部分主流瀏覽器都支持,能夠安心的往下看了。android
rem設置字體大小ios
rem是(font size of the root element),官方解釋css3
意思就是根據網頁的根元素來設置字體大小,和em(font size of the element)的區別是,em是根據其父元素的字體大小來設置,而rem是根據網頁的跟元素(html)來設置字體大小的,舉一個簡單的例子,web
如今大部分瀏覽器IE9+,Firefox、Chrome、Safari、Opera ,若是咱們不修改相關的字體配置,都是默認顯示font-size是16px即chrome
html { font-size:16px; }
那麼若是咱們想給一個P標籤設置12px的字體大小那麼用rem來寫就是
p { font-size: 0.75rem; //12÷16=0.75(rem) }
基本上使用rem這個單位來設置字體大小基本上是這個套路,好處是假如用戶本身修改了瀏覽器的默認字體大小,那麼使用rem時就能夠根據用戶的調整的大小來顯示了。可是rem不只能夠適用於字體,一樣能夠用於width height margin這些樣式的單位。下面來具體說一下
rem進行屏幕適配
在講rem屏幕適配以前,先說一下通常作移動端適配的方法,通常能夠分爲:
簡單一點的頁面,通常高度直接設置成固定值,寬度通常撐滿整個屏幕。
稍複雜一些的是利用百分比設置元素的大小來進行適配,或者利用flex等css去設置一些須要定製的寬度。
再複雜一些的響應式頁面,須要利用css3的media query屬性來進行適配,大體思路是根據屏幕不一樣大小,來設置對應的css樣式。
上面的一些方法,其實也能夠解決屏幕適配等問題,可是既然出來的rem這個新東西,也必定能兼顧到這些方面,下面具體使用rem:
rem適配
先看一個簡單的例子:
.con { width: 10rem; height: 10rem; }
這是一個div,寬度和高度都用rem來設置了,在瀏覽器裏面是這樣顯示的,能夠看到,在瀏覽器裏面width和height分別是160px,正好是16px * 10,那麼若是將html根元素的默認font-size修改一下呢?
html { font-size: 17px; } .con { width: 10rem; height: 10rem; }
再來看看結果:
這時width和height都是170px,這就說明了將rem應用與width和height時,一樣適用rem的特性,根據根元素的font-size值來改變自身的值,由此咱們應該能夠聯想到咱們能夠給html設定不一樣的值,從而達到咱們css樣式中的適配效果。
rem數值計算
若是利用rem來設置css的值,通常要經過一層計算才行,好比若是要設置一個長寬爲100px的div,那麼就須要計算出100px對應的rem值是 100 / 16 =6.25rem,這在咱們寫css中,其實算比較繁瑣的一步操做了。
對於沒有使用sass的工程:
爲了方便起見,能夠將html的font-size設置成100px,這樣在寫單位時,直接將數值除以100在加上rem的單位就能夠了。
對於使用sass的工程:
前端構建中,徹底能夠利用scss來解決這個問題,例如咱們能夠寫一個scss的function px2rem即:
@function px2rem($px){ $rem : 37.5px; @return ($px/$rem) + rem; }
這樣,當咱們寫具體數值的時候就能夠寫成:
height: px2rem(90px); width: px2rem(90px);;
看到這裏,你可能會發現一些不理解的地方,就是上面那個rem:37.5px是怎麼來的,正常狀況下不是默認的16px麼,這個其實就是頁面的基準值,和html的font-size有關。
rem基準值計算
關於rem的基準值,也就是上面那個37.5px實際上是根據咱們所拿到的視覺稿來決定的,主要有如下幾點緣由:
因爲咱們所寫出的頁面是要在不一樣的屏幕大小設備上運行的
因此咱們在寫樣式的時候必需要先以一個肯定的屏幕來做爲參考,這個就由咱們拿到的視覺稿來定
假如咱們拿到的視覺稿是以iphone6的屏幕爲基準設計的
iPhone6的屏幕大小是375px,
rem = window.innerWidth / 10
這樣計算出來的rem基準值就是37.5(iphone6的視覺稿),這裏爲何要除以10呢,其實這個值是隨便定義的,由於不想讓html的font-size太大,固然也能夠選擇不除,只要在後面動態js計算時保證同樣的值就能夠,在這裏列舉一下其餘手機的
iphone3gs: 320px / 10 = 32px
iphone4/5: 320px / 10 = 32px
iphone6: 375px / 10 =37.5px
動態設置html的font-size
如今關鍵問題來了,咱們該如何經過不一樣的屏幕去動態設置html的font-size呢,這裏通常分爲兩種辦法
1利用css的media query來設置即
@media (min-device-width : 375px) and (max-device-width : 667px) and (-webkit-min-device-pixel-ratio : 2){ html{font-size: 37.5px;} }
2利用javascript來動態設置根據咱們以前算出的基準值,咱們能夠利用js動態算出當前屏幕所適配的font-size即:
document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px';
而後咱們看一下以前那個demo展現的效果
.con { width: px2rem(200px); height: px2rem(200px); } document.addEventListener('DOMContentLoaded', function(e) { document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px'; }, false);
iPhone6下,正常顯示200px
在iphone4下,顯示169px
因而可知咱們能夠經過設置不一樣的html基礎值來達到在不一樣頁面適配的目的,固然在使用js來設置時,須要綁定頁面的resize事件來達到變化時更新html的font-size。
rem適配進階
咱們知道,通常咱們獲取到的視覺稿大部分是iphone6的,因此咱們看到的尺寸通常是雙倍大小的,在使用rem以前,咱們通常會自覺的將標註/2,其實這也並沒有道理,可是當咱們配合rem使用時,徹底能夠按照視覺稿上的尺寸來設置。
1 設計給的稿子雙倍的緣由是iphone6這種屏幕屬於高清屏,也便是設備像素比(device pixel ratio)dpr比較大,因此顯示的像素較爲清晰。
2 通常手機的dpr是1,iphone4,iphone5這種高清屏是2,iphone6s plus這種高清屏是3,能夠經過js的window.devicePixelRatio獲取到當前設備的dpr,因此iphone6給的視覺稿大小是(*2)750×1334了。
3 拿到了dpr以後,咱們就能夠在viewport meta頭裏,取消讓瀏覽器自動縮放頁面,而本身去設置viewport的content例如(這裏之因此要設置viewport是由於咱們要實現border1px的效果,加入我給border設置了1px,在scale的影響下,高清屏中就會顯示成0.5px的效果)
meta.setAttribute('content', 'initial-scale=' + 1/dpr + ', maximum-scale=' +1/dpr + ', minimum-scale=' + 1/dpr + ', user-scalable=no');
4 設置完以後配合rem,修改
@function px2rem($px){ $rem : 75px; @return ($px/$rem) + rem; }
雙倍75,這樣就能夠徹底按照視覺稿上的尺寸來了。不用在/2了,這樣作的好處是:
解決了圖片高清問題。
解決了border 1px問題(咱們設置的1px,在iphone上,因爲viewport的scale是0.5,因此就天然縮放成0.5px)
在iphone6下的例子:
咱們使用動態設置viewport,在iphone6下,scale會被設置成1/2即0.5,其餘手機是1/1即1.
咱們的css代碼,注意這裏設置了1px的邊框
.con { margin-top: 200px; width: 5.3rem; height: 5.3rem; border-top:1px solid #000; }
在iphone6下的顯示:
在android下的顯示:
rem進行屏幕適配總結
下面這個網址是針對rem來寫的一個簡單的demo頁面,你們能夠在不一樣的手機上看一下效果
可是rem也並非萬能的,下面也有一些場景是不適於使用rem的
1當用做圖片或者一些不能縮放的展現時,必需要使用固定的px值,由於縮放可能會致使圖片壓縮變形等。