移動 Web 適配利器:rem

提到rem,你們首先會想到的是em,px,pt這類的詞語,大多數人眼中這些單位是用於設置字體的大小的,沒錯這的確是用來設置字體大小的,可是對於rem來講它能夠用來作移動端的響應式適配哦。javascript

兼容性css

先看看兼容性,關於移動端html

  • ios:6.1系統以上都支持前端

  • android:2.1系統以上都支持java

大部分主流瀏覽器都支持,能夠安心的往下看了。android

rem設置字體大小ios

rem是(font size of the root element),官方解釋css3

意思就是根據網頁的根元素來設置字體大小,和em(font size of the element)的區別是,em是根據其父元素的字體大小來設置,而rem是根據網頁的跟元素(html)來設置字體大小的,舉一個簡單的例子,web

如今大部分瀏覽器IE9+,FirefoxChromeSafariOpera ,若是咱們不修改相關的字體配置,都是默認顯示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屏幕適配以前,先說一下通常作移動端適配的方法,通常能夠分爲:

  1. 簡單一點的頁面,通常高度直接設置成固定值,寬度通常撐滿整個屏幕。

  2. 稍複雜一些的是利用百分比設置元素的大小來進行適配,或者利用flex等css去設置一些須要定製的寬度。

  3. 再複雜一些的響應式頁面,須要利用css3media 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實際上是根據咱們所拿到的視覺稿來決定的,主要有如下幾點緣由:

  1. 因爲咱們所寫出的頁面是要在不一樣的屏幕大小設備上運行的

  2. 因此咱們在寫樣式的時候必需要先以一個肯定的屏幕來做爲參考,這個就由咱們拿到的視覺稿來定

  3. 假如咱們拿到的視覺稿是以iphone6的屏幕爲基準設計的

  4. 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事件來達到變化時更新htmlfont-size。

rem適配進階

咱們知道,通常咱們獲取到的視覺稿大部分是iphone6的,因此咱們看到的尺寸通常是雙倍大小的,在使用rem以前,咱們通常會自覺的將標註/2,其實這也並沒有道理,可是當咱們配合rem使用時,徹底能夠按照視覺稿上的尺寸來設置。

設計給的稿子雙倍的緣由是iphone6這種屏幕屬於高清屏,也便是設備像素比(device pixel ratio)dpr比較大,因此顯示的像素較爲清晰。

通常手機的dpr是1,iphone4iphone5這種高清屏是2,iphone6s plus這種高清屏是3,能夠經過js的window.devicePixelRatio獲取到當前設備的dpr,因此iphone6給的視覺稿大小是(*2)750×1334了。

拿到了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');

設置完以後配合rem,修改

@function px2rem($px){ $rem : 75px; @return ($px/$rem) + rem; }

雙倍75,這樣就能夠徹底按照視覺稿上的尺寸來了。不用在/2了,這樣作的好處是:

  1. 解決了圖片高清問題。

  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值,由於縮放可能會致使圖片壓縮變形等。

相關文章
相關標籤/搜索