rem : web app適配的祕密武器

最近看到這樣一個提問:我有一個750 x 1500尺寸的設計稿,設計稿上有一個150 x 50的按鈕,那麼在寫頁面佈局的時候,應該如何肯定按鈕的尺寸呢?。大多數同窗在回答的時候提到了rem。但我發現不少同窗對於rem的實際應用還存在一點小小的疑問和誤解。css

因而問題來了,rem究竟是什麼?rem是爲了解決什麼問題而存在的?rem可以給咱們帶來什麼樣的便利?帶着這樣的問題,咱們一塊兒來總結一下rem的實踐。恰好工做中有一個移動端頁面的需求要作,就嘗試使用rem完成了一個小小的頁面適配。你們能夠點擊這裏,查看rem適配demohtml

建議你們在chrome的device module下打開,經過切換不一樣手機的模擬器來查看不一樣尺寸下的區別。ios

rem是什麼?

rem是一個相對於根元素字體大小的css單位。與px同樣,他能夠用來設置字體大小,也能夠用來設置長度單位。相對於根元素字體大小是什麼意思?web

舉個栗子。在頁面中,html元素是根元素,所以咱們首先給html設置一個字體大小chrome

html { font-size: 100px; }

因而,在整個頁面中,就有這樣的換算公式 : 1rem = 100pxsegmentfault

因此若是一個按鈕,有以下的css樣式,就等同於他的寬爲100px,高50px.瀏覽器

btn { width: 1rem; height: 0.5rem; }

這就是rem這個知識點的全部真相了。app

!!!什麼?這就完了?這和px有什麼區別?iphone

對啊,這和px原本就沒有特別的區別,就是一個尺寸單位嘛!佈局

因此提問的那個同窗拿着750x1500設計圖來問,當咱們設置爲html的字體大小爲100px時,
150x50的按鈕應該在頁面裏面寫什麼尺寸?,用px就應該寫 75x25,用rem就是 0.75 x 0.25.

真實寬度375px / 設計圖寬度750px = 按鈕真實寬度 / 設計圖按鈕寬度150px
==> 按鈕真實寬度 = 75px

又 1rem = 100px;   ==> 75px = 0.75rem

有的時候咱們但願在設計圖直接量出來的尺寸不用除2直接獲得rem的值,也就是說量出來是150px,那麼用rem表示就是1.5rem。這個時候咱們只須要修改html的字體大小爲50px便可。那麼計算思路就有一點不一樣。

真實寬度375px / 設計圖寬度750px = 按鈕真實寬度 / 設計圖按鈕寬度150px
==> 按鈕真實寬度 = 75px

又 1rem = 50px;   ==> 75px = 1.5rem

所以當設計圖的尺寸發生改變時,咱們須要根據上述思路,動態的調整html的字體大小,以達到咱們想要的rem換算。

rem是爲了解決什麼問題而存在的?

以iphone各類手機的尺寸來講,iPhone4,5 寬度320px,iPhone6 375px,iPhone6 plus 414px. 若是一個按鈕,固定一個75x25的尺寸,那麼就必然會致使在不一樣尺寸下的相對大小不同。這帶來的問題就在於會直接影響到設計的美觀,可能在iPhone6下,一個完美的設計圖,到了iPhone5,就變得low不少。 由於,爲了讓頁面元素的尺寸可以在設備寬度變化的時候也跟着變化,rem就出現了。

咱們已經知道,rem的相對大小跟html元素的字體大小有關係。使用rem適配的原理就是咱們只須要在設備寬度大小變化的時候,調整html的字體大小,那麼頁面上全部使用rem單位的元素都會相應的變化。 這也是rem與px最大的區別。

有css與js兩種方式來調整html元素大小的值。

css方式

html { font-size: calc(100vw / 3.75) }

100vw表示設備寬度,除以3.75這裏是以iphone6 的寬度375px爲標準,爲了保證html的字體大小爲100px。這樣咱們在換算的時候,1px 就是0.01rem,就很容易計算。

由於chrome下最小字體大小爲12px,因此不能把html的font-size設置成1px或者10px,100px是咱們最好的選擇。

js方式, 原理與css同樣,不過爲了不在一些老舊一點的手機瀏覽器上不支持calc,vm這些屬性,在實際應用中使用js是最好的。

!function () {
   function a() {
       var _width;
       var clientWidth = document.documentElement.clientWidth;
       if (clientWidth > 568) {
           _width = 568;
       } else if (clientWidth < 320) {
           _width = 320;
       } else {
               _width = clientWidth;
       }
       // var pageWid = (window.innerWidth > document.querySelector('body').offsetHeight) ? 1136 : 640;
       document.documentElement.style.fontSize = _width / 375 * 100 + "px";
   }
   var b = null;
   document.addEventListener("DOMContentLoaded", function () {
       window.addEventListener("resize", function () {
           clearTimeout(b);
           b = setTimeout(a, 300)
       }, !1);
       a()
   }, false);
}(window);

在實踐中還有一個關鍵的問題須要處理。就是不管如何js的加載會比css慢,所以若是咱們就這樣的話,頁面的元素會有一個很明顯的閃爍過程,由於再js加載進來以前,html的字體大小尚未達到咱們想要的效果。所以一般咱們須要在css中,給html的字體大小設置一個默認值,以弱化這個閃爍的過程。默認值的具體大小須要咱們自行根據設計圖的尺寸,以及你想要的結果,經過上面咱們介紹的計算思路去得出。

html {
  font-size: 100px;
}
須要注意的地方

1、rem的適用性頗有侷限,僅僅只可以用於只在移動端展現的頁面。若是你的頁面還須要適配到pc端,那麼就老老實實的使用px吧。在上面的實現中,我經過判斷設定了html字體大小的範圍來避免pc上顯示過於誇張。

2、有的同窗可能對web的適配有點誤解。web中作適配並不須要考慮什麼物理像素啊,dpi等等概念。這些應該僅僅只是Android或者ios原生app纔會考慮的問題。這些誤會致使許多搞設計的同窗在給web app作設計的時候,也丟一張1080 x 1920 的設計稿過來,真是愁死人了。

clipboard.png

相關文章
相關標籤/搜索