前端Css之rem相對單位

爲何要使用rem


以前有些適配作法,是經過js動態計算viewport的縮放值(initial-scale)。css

例如以屏幕320像素爲基準,設置1,那屏幕375像素就是375/320=1.18以此類推。html

但直接這樣強制頁面縮放過於粗暴,會致使頁面圖片文字失真模糊。html5

Px是相對固定單位,字號大小直接被定死,因此用戶沒法根據本身設置的瀏覽器字號而縮放,em和rem雖然都是相對單位,但em是相對於它的父元素的font-size,頁面層級越深,em的換算就越複雜,而rem是直接相對於根元素,這就避開了不少層級關係。移動端新型瀏覽器對rem的兼容很好,能夠放心使用。css3

通用換算和一些坑


有時咱們會看到有些使用rem的頁面裏會先給頁面根元素一個樣式:git

html {font-size: 62.5%; /*10 ÷ 16 × 100% = 62.5%*/}

爲何是62.5%?github

大多數瀏覽器的默認字號是16px,所以1rem=16px,這樣不方便咱們px和rem的換算,假設1rem=10px,那麼100px=10rem,25px=0.25rem。這樣就好換算不少,因而就有了上面的10/16。算法

若是是640的設計稿,須要除以2轉化爲和iphone5屏幕等寬的320。因此設計稿px單位/2/10轉爲rem。以後再媒體查詢設置每一個屏幕大小的font-size百分比,頁面會根據上面設置的根font-size適配。chrome

看到這裏是否是以爲一切很完美?然而,這裏面有兩個深坑:瀏覽器

1.我看了網上不少關於rem的資料,基本都說瀏覽器的默認字號就是16px,而後直接定義font-size:62.5%。可是,rem屬於css3的屬性,有些瀏覽器的早期版本和一些國內瀏覽器的默認字號並非16px,那麼上面的10/16換算就不成立,直接給html定義font-size: 62.5%不成立。sass

2.chrome強制字體最小值爲12px,低於12px按12px處理,那上面的1rem=10px就變成1rem=12px,出現誤差(下面給demo)。

解決方案: 將1rem=10px換爲1rem=100px(或者其它容易換算的比例值);不要在pc端使用rem。

那麼上面的頁面根元素樣式要改成:

html {font-size: 625%; /*100 ÷ 16 × 100% = 625%*/}

再用本工廠總結得出的各分辨率媒體查詢換算:

@media screen and (min-width:360px) and (max-width:374px) and (orientation:portrait) {
    html { font-size: 703%; }
}
@media screen and (min-width:375px) and (max-width:383px) and (orientation:portrait) {
    html { font-size: 732.4%; }
}
@media screen and (min-width:384px) and (max-width:399px) and (orientation:portrait) {
    html { font-size: 750%; }
}
@media screen and (min-width:400px) and (max-width:413px) and (orientation:portrait) {
    html { font-size: 781.25%; }
}
@media screen and (min-width:414px) and (max-width:431px) and (orientation:portrait){
    html { font-size: 808.6%; }
}
@media screen and (min-width:432px) and (max-width:479px) and (orientation:portrait){
    html { font-size: 843.75%; }
}

至此,坑填完。設計稿px換算直接/100便可獲得rem值。

更精準健壯的換算


然而,上面的625%大法除了有兼容性問題,也沒法很好地根據不一樣設計稿精準適配,不是咱們的最佳選擇。網易和淘寶分別有本身的一套適配方法,適配性也很完美。

  • 網易手機端:技術分享技術分享技術分享基準值: 能夠看到,不管頁面以哪一種手機比例縮放,body的width都是7.5rem。很明顯,目前網易的手機端設計稿是基於iPhone6,750(設計師給的設計稿是物理分辨率,會是咱們寫樣式的邏輯分辨率的兩倍,若是給的設計稿是640,那麼是基於iPhone5,320),且基準值是100px(750/7.5=100)。這個基準值很關鍵,後面的css換算,都和這個基準值有關。動態font-size: 咱們看到圖一、圖二、圖3的font-size都有根據屏幕大小而動態改變,能夠推算出公式:

    屏幕寬度/設計稿rem寬度=頁面動態font-size值(如:375/7.5=50)

    獲取到這個值,再賦給html元素的style:

    document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + ‘px‘;
    

    這樣就設置好了每一個頁面的根fonts-size,由於rem單位是基於根font-size,所以只要肯定一種設計稿對應手機的換算,其他屏幕尺寸都可自動適配。

    上面咱們得出設計稿換算rem的基準值是100,所以只須要把設計稿上的px值除以100即爲咱們要的rem值。

    > Px/100=rem,因此100px=1rem,25px=0.25rem
    
  • 淘寶手機端:  大名鼎鼎的Flexible

    資料引用

    大漠:使用Flexible實現手淘H5頁面的終端適配

    齊神:flexible解讀及應用

     

    不少大神包括咱們公司同事都有對此適配方案作了解析,因此我這邊簡單綜述:

    引入: 直接引用阿里的CDN文件(或下載到本地引入)

    <script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>
    

    設定: 頁面不要設定 。Flexible會自動設定每一個屏幕寬度的根font-size、動態viewport、針對Retina屏作的dpr。

    換算: 假設拿到的設計稿和上述網易的同樣都是750,Flexible會把設計稿分爲10份,能夠理解爲頁面width=10rem,即1rem=75px,因此根font-size(基準值)=75px。

以後的css換算rem公式爲:

px/75=rem,因此100px=100/75=1.33rem,50px=50/75=0.66rem

換算工具


顯然,能夠看出px與rem的換算由於基準值的不一樣而有些複雜,甚至須要藉助計算器的輔助。在這裏推薦一個換算神器:cssrem

安裝好以後,作一些設置

px_to_rem - px轉rem的單位比例,假設拿到設計稿750,基準值是75,此處就設75

max_rem_fraction_length - px轉rem的小數部分的最大長度。默認爲6。

available_file_types - 啓用此插件的文件類型。[".css", ".less", ".sass", ".scss"]。技術分享

上述三種換算方案的步驟和優劣


  • 通用方案

一、設置根font-size:625%(或其它自定的值,但換算規則1rem不能小於12px)

二、經過媒體查詢分別設置每一個屏幕的根font-size

三、css直接除以2再除以100便可換算爲rem。

優:有必定適用性,換算也較爲簡單。

劣:有兼容性的坑,對不一樣手機適配不是很是精準;須要設置多個媒體查詢來適應不一樣手機,單某款手機尺寸不在設置範圍以內,會致使沒法適配。

  • 網易方案

一、拿到設計稿除以100,獲得寬度rem值

二、經過給html的style設置font-size,把1裏面獲得的寬度rem值代入x  document.documentElement.style.fontSize = document.documentElement.clientWidth / x + ‘px‘;

三、設計稿px/100便可換算爲rem

優:經過動態根font-size來作適配,基本無兼容性問題,適配較爲精準,換算簡便。

劣:無viewport縮放,且針對iPhone的Retina屏沒有作適配,致使對一些手機的適配不是很到位。

 

網易rem方案:

 

前提:

 

<meta name="viewport" content="initial-scale=1,maximum-scale=1, minimum-scale=1">

  

優點:

  不用管DPR,只需知設計稿寬度

 

已知:

  假設現有iPhone6設計稿,寬750px,其中一元素寬150px;

根據DPR值,iPhone6的DPR值爲2,咱們可得其中該元素的顯示尺寸:

真實顯示CSS值:

 

 

如今咱們用網易方案來解決這個問題:

  首先咱們取1rem = 100px爲參考值(這個值能夠隨便取,爲什麼取這個值容後解答)

  可知body的寬度:

 

  又由於body的寬度爲7.5rem,由「網易公式」可得:

  Html的font-size爲:

 

  Dw爲deviceWidth,即設備寬度,這是整個方案裏惟一動態改變的值

  現咱們已知設計稿爲iPhone6,又知iPhone6的設備寬爲375px,

  這時候咱們再回頭看:

  html當前設備的font-size:

 

  且:

 

  可知,無形中這步已幫咱們做了DPR換算;750px的設計稿,顯示在375px的屏幕要怎樣轉換。

  前面咱們取了1rem = 100px,可得該元素寬:150px = 1.5rem,

  又知rem爲其餘元素相對根元素(html)的大小

  因此可得當前元素寬度的真實css顯示值爲:1.5rem*50px = 75px;(這裏的75px就跟咱們前面理想獲得的75px不謀而合了)。

  這邊咱們把這個運算再拆解來看:

 

  現再回頭看:就能夠知道爲何當時要取100px爲參考值,取這個值的意義就是爲了方便運算。

 

 

總結:

  咱們只需以iPhone6的設計稿(當前主導的機型),750px寬完成一套頁面,當去到其餘設備時,由於咱們用的都是rem值,只須要經過JS動態得到當前的dw,再經過動態獲取的dw改變html的font-size值,頁面的其餘元素也會由於html的改變而進行等比例縮放。

 

 

步驟:

  1.根據設計稿尺寸完成頁面;

  2.設置meta,控制視口寬度,讓頁面以1:1比例渲染頁面

  3.動態設置html的font-size;

  4.把各元素的px值除以100轉換爲rem(字體除外)

 

網易方案關鍵代碼:

    設置視口: 

<meta name="viewport" content="initial-scale=1,maximum-scale=1, minimum-scale=1">

    動態設置html的font-size:

document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + 'px';
  • 手淘方案

一、拿到設計稿除以10,獲得font-size基準值

二、引入flexible

三、不要設置meta的viewport縮放值

四、設計稿px/ font-size基準值,便可換算爲rem

優:經過動態根font-size、viewpor、dpr來作適配,無兼容性問題,適配精準。

劣:須要根據設計稿進行基準值換算,在不使用sublime text編輯器插件開發時,單位計算複雜。

Demo


下面看看demo

設計稿:基於iPhone5,寬度640。

那麼在開發模式,iphone5是320,全部數值均是設計稿一半大小。

指望效果:在iPhone5中,box1寬高50px,box2寬高125px,字體15px。其餘屏幕終端自動適配。

技術分享

一、62.5%方案

能夠看出,基於chrome iPhone5的調試,box1寬高是60,box2寬高是150。出現了偏差,就是上文提到字號最小值強制12px的緣由。

二、625%方案

比例正常。

三、網易方案

比例正常。

四、手淘方案

比例正常(Retina屏作了縮放)。

到底用哪一種換算方案呢?


每一個人評判的標準不一樣。但我的更傾向flexible,動態計算viewport和針對iphone手機的dpr縮放使得頁面適配更加精確,並且手淘頁面用戶訪問量比網易頁面大不少。

移動端有用px的時候嗎?


有。當你的頁面圖片或者某一元素比例要固定,不想進行任何縮放時,rem就不適合了,這時候用px單位,能保證該元素不會因縮放而失真模糊。

 

 

 

 

首先,先說一個常識,瀏覽器的默認字體高都是16px。步入正題-----〉

  • 兼容性:

目前,IE9+,Firefox、Chrome、Safari、Opera 的主流版本都支持了rem。

就算對不支持的瀏覽器,應對方法也很簡單,就是多寫一個絕對單位的聲明。這些瀏覽器會忽略用rem設定的字體大小。

  • 使用%單位方便使用
css中的body中先全局聲明font-size=62.5%,這裏的%的算法和rem同樣。
由於100%=16px,1px=6.25%,因此10px=62.5%,
這是的1rem=10px,因此12px=1.2rem。px與rem的轉換經過10就能夠得來,很方便了吧!
  •  使用方法

注意,rem是只相對於根元素htm的font-size,即只須要設置根元素的font-size,其它元素使用rem單位設置成相應的百分比便可;

例子:

1 /*16px * 312.5% = 50px;*/
2 html{font-size: 312.5%;}
1 /*50px * 0.5 = 25px;*/
2 body{
3     font-size: 0.5rem;
4     font-size\0:25px;
5 }

通常狀況下,是這樣子使用的

1 html{font-size:62.5%;} 
2 body{font-size:12px;font-size:1.2rem ;} 
3 p{font-size:14px;font-size:1.4rem;}
  • 優勢

用一個東西確定要知道它的好處啦,因爲其餘字體大小都是基於html的,因此在移動端作適配的時候,可使用這樣的方法

複製代碼
 1 @media only screen and (min-width: 320px){
 2   html {
 3     font-size: 62.5% !important;
 4   }
 5 }
 6 @media only screen and (min-width: 640px){
 7   html {
 8     font-size: 125% !important;
 9   }
10 }
11 @media only screen and (min-width: 750px){
12   html {
13     font-size: 150% !important;
14   }
15 }
16 @media only screen and (min-width: 1242px){
17   html {
18     font-size: 187.5% !important;
19   }
20 }
複製代碼

這樣子就能作到僅僅改變html的字體大小,讓其餘字體具備「響應式」啦。

又是午睡時間,若是本文有不正確的地方,請指出^_^

相關文章
相關標籤/搜索