rem與px換算的計算方式


前言

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

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

1.什么是rem

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

所以這里總結一句,所謂依賴根元素來計算的方式,就是先給予html元素一個font-size,然后我們所有的rem就根據這個font-size來計算

例如:

1
html{  font-size : 16px ;}

 那么我們這里的1rem就應該這么來計算:1x16=16px=1rem;瀏覽器默認為16px可能造成rem計算上的麻煩和多位小數,所以,我們也可以進行這種方式的初始化根元素:

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.html

 至於為什么要加入viewport,我覺得就是因為現在市面上雖然有那么多不同種類不同品牌不同分辨率的手機,但它們的理想viewport寬度歸納起來無非也就 320、360、414、等幾種,都是非常接近的,理想寬度的相近也就意味着我們針對某個設備的理想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的一些總結和整理,希望能對看到這篇博客的人有所幫助,也希望能有大神在評論里指出我的不足之處。

 完結撒花~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM