rem與px換算的計算方式

前言

這段時間的小項目中算是真正意義上使用了rem來進行移動端的頁面佈局,項目結束了我反思了一下以前的對於rem的使用...原來我之前對rem用法徹底是在搞笑啊!!結合此次這個小項目,我以爲我也有必要對rem佈局以及用法進行一次總結。javascript

ps.文筆可能不太好...css

1.什麼是rem

來自於鵝廠ISUX團隊的解釋以下: rem(font size of the root element)是指相對於根元素的字體大小的單位。簡單的說它就是一個相對單位。看到rem你們必定會想起em單位,em(font size of the element)是指相對於父元素的字體大小的單位。它們之間其實很類似,只不過一個計算的規則是依賴根元素一個是依賴父元素計算。html

因此這裏總結一句,所謂依賴根元素來計算的方式,就是先給予html元素一個font-size,而後咱們全部的rem就根據這個font-size來計算java

例如:web

1
html{  font-size : 16px ;}

 那麼咱們這裏的1rem就應該這麼來計算:1x16=16px=1rem;瀏覽器默認爲16px可能形成rem計算上的麻煩和多位小數,因此,咱們也能夠進行這種方式的初始化根元素:chrome

1
2
3
html{
    font-size= 62.5%  //這裏就是 10 / 16 x 100% = 62.5%  也就是默認 10px 的字號
}

 這樣初始化以後,咱們來進行rem計算的時候,就會減小許多的麻煩。瀏覽器

 2.設置viewport配合進行縮放

一般在寫移動端頁面的時候,咱們都會設置viewport,保證頁面縮放沒有問題,最多見的viewport的meta標籤以下:架構

1
< meta  name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

 這個標籤的參數就再也不作詳細解釋,若是有須要瞭解詳細的參數分析與解釋,能夠參考個人這篇博文:http://www.cnblogs.com/azhai-biubiubiu/p/5305022.htmlless

 至於爲何要加入viewport,我以爲就是由於如今市面上雖然有那麼多不一樣種類不一樣品牌不一樣分辨率的手機,但它們的理想viewport寬度概括起來無非也就 320、360、41四、等幾種,都是很是接近的,理想寬度的相近也就意味着咱們針對某個設備的理想viewport而作出的網站,在其餘設備上的表現也不會相差很是多甚至是表現同樣的。佈局

3.怎麼樣在不一樣分辨率的狀況下計算根元素須要的font-size的值

 關於這個點,其實有兩種解決方案,一種是基於CSS的狀況,另一種就要經過js計算得到

a.基於CSS

通常咱們作頁面,確定都會有設計圖,移動端頁面,通常狀況下,UI出圖都會定寬爲640px,這也是移動端的標準尺寸;可是,咱們也不能排除可能有其餘特殊的狀況可能須要作其餘大小的設計圖。因此,咱們能夠先定一個基準,而後來看看isux團隊的整理出來的一個表格:

                          

經過表格,咱們能很清楚的看出各類分辨率下該如何計算,例如:320下的html的font-size就應該爲320/640=0.5 因此,當以640爲基準的font-size是20px時,咱們就應該給320的定義爲10px;

怎麼作到基於不一樣的分辨率來定義呢?不用說,首先想到的確定就是媒體查詢。當咱們基於媒體查詢來作屏幕自適應時,首先要考慮下須要作那些屏幕,畢竟時下各類類型的手機讓人眼花繚亂,分辨率也是多種多樣,這裏我作一下簡單的例舉,是我在過往項目中涉及到常見的屏幕分辨率的媒體查詢:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@media only  screen  and (min-device- width 320px )and (-webkit-min-device-pixel-ratio:  2 ) {
    //針對iPhone  4 5 c, 5 s, 全部iPhone 6 的放大模式,個別iPhone 6 的標準模式<br>  html{<br>     font-size : 10px ;<br>  }
}
@media only  screen  and (min-device- width 375px )and (-webkit-min-device-pixel-ratio:  2 ) {
  //針對大多數iPhone 6 的標準模式<br>  html{<br>     font-size : 12px ;<br>  }
}
   
@media only  screen  and (min-device- width 375px )and (-webkit-min-device-pixel-ratio:  3 ) {
  //針對全部iPhone 6 +的放大模式<br>  html{<br>     font-size : 16px ;<br>  }
   
}
@media only  screen  and (min-device- width : 412px ) and (-webkit-min-device-pixel-ratio:  3 ) {
  //針對全部iPhone 6 +的標準模式, 414px 寫爲 412px 是因爲三星Nexus  6 412px ,可一併處理<br>  html{<br>     font-size : 20px ;<br>  }
}

 上述爲現階段常見的iPhone系列的媒體查詢,對於安卓方面,我發現好像只要作好了6p+和6的,基本在安卓主流機型上的表現都會很好。可是考慮到有些其餘的項目可能會出現向下兼容較低版本的狀況,我這邊提供幾個媒體查詢的例子,可是具體的數值,我以爲可能須要你們自行計算一下。

1
2
3
4
5
6
7
8
9
10
11
@media only  screen  and (-webkit-device-pixel-ratio:. 75 ){  /*低分辨率小尺寸的圖片樣式*/
 
}
 
@media only  screen  and (-webkit-device-pixel-ratio: 1 ){  /*普通分辨率普通尺寸的圖片樣式*/
 
}
 
@media only  screen  and (-webkit-device-pixel-ratio: 1.5 ){  /*高分辨率大尺寸的圖片樣式*/
 
}

 b.基於JS進行屏幕分辨率計算

咱們來看這麼一段js:

1
2
3
4
5
6
7
8
9
10
11
12
13
( function  (doc, win) {
     var  docEl = doc.documentElement,
         resizeEvt =  'orientationchange'  in  window ?  'orientationchange'  'resize' ,
         recalc =  function  () {
             var  clientWidth = docEl.clientWidth;<br>       window.innerWidth>max ?  window.innerWidth : max;
             if  (!clientWidth)  return ;
             docEl.style.fontSize = 20 * (clientWidth / 320) +  'px' ;
         };
 
     if  (!doc.addEventListener)  return ;
     win.addEventListener(resizeEvt, recalc,  false );
     doc.addEventListener( 'DOMContentLoaded' , recalc,  false );
})(document, window);

 其實有點尷尬的問題在於...這段代碼的詳細做用我也未能徹底理解,可是經過其中的某些關鍵詞,我先作下大體的分析:

 orientationchange:這是一個事件,菜鳥教程中作了這麼一個解釋:事件是在用戶水平或者垂直翻轉設備(即方向發生變化)時觸發的事件。

 如下理解,可能並非很準確!!只是讓我本身明白了是個啥東西!各位千萬別被帶坑裏去了!也但願大神在底下指正分析下這段代碼!

 其實這段代碼,主要起到的做用是監聽,代碼的核心就是這麼一句:

1
docEl.style.fontSize = 20 * (clientWidth / 320) +  'px' ;

 這句話決定了幾個關鍵:1.基於根元素計算rem所須要的font-size;2.規定了設計圖的基準尺寸以及基準的font-size。因此,在須要用到這段JS的時候,咱們只須要根據UI設計圖,規定好基準的font-size和統一的UI設計圖尺寸就行了。

基於這段JS,咱們的項目處理中也利用了這種方式,可是不一樣的是並無使用JS,而是根據這種預約義基準量的方式,在less中進行計算後獲得能夠自適應的尺寸

1
2
3
4
5
//html  font-size 20 -40
//對應屏幕寬度 320 -640
//當前設計稿是 750 ,咱們用設計稿 100% 的寬度來測量比較方便,
//因此須要base換算
@base: ( 640 / 750 )/ 40 rem;//rem是最後算出結果的單位

 而後看看下面這個例子:

1
2
3
4
5
6
7
8
.tag {
   display : inline- block ;
   font-size 22 *@base;
   text-align center ;
   border-radius:  20px ;
   margin-bottom 20 *@base;
   padding : 10 *@base  20 *@base;
}

 例子中的@base就是預編譯好的,能夠進行計算的基準變量,而後例子中的尺寸變化,我是根據UI的PSD中百分百尺寸下的測量獲得的數值乘以基準值。這樣作可能有些麻煩,可是好處在於對於UI的還原度會特別高,基本能夠作到像素級的UI還原,那咱們來看看效果:

                                          

能夠看出,在chrome的移動端模擬器下,大、中、小三種分辨率下,佈局並無產生變化,發生變化的僅僅只有內容而已。在移動端代碼中,咱們通常只會定義元素的width,使其height自適應,可是使用這種變量的形式,height也能夠進行定義,使咱們的CSS更爲嚴謹些。

 

4.流式佈局與rem佈局的區別

 在流式佈局下:

 網頁的主要架構部分按照百分比佈局,寬度百分比,高度定死;

 若是是圖片寬度設置百分比,高度根據圖片的比例自適應,若是是封面圖片能夠高度定死,用background-size:cover顯示部分就行;

 在rem佈局下,以前已經說了不少,這裏就說下和流式佈局的區別:

 rem佈局須要基於根元素的基準量來作的,不一樣屏幕分辨率設置不一樣的基準量,那麼對UI的還原度就會很高,可是...發現了一個rem的問題...就是若是頁面設計比較看重元素間隔和高度的話...那麼用rem佈局就會比較難受

 

5.總結下

 其實在實際項目中,感受使用rem仍是比較方便的,並且學習成本也不高。若是有同窗遇到移動端項目而不須要考慮PC端的話,rem絕對能讓人寫CSS比較舒服。

 

 學無止境,以上就是我對rem的一些總結和整理,但願能對看到這篇博客的人有所幫助,也但願能有大神在評論裏指出個人不足之處。

 完結撒花~

相關文章
相關標籤/搜索