Rem的深入理解

什么是em?

css中有兩個常用的相對單位,em和rem,先有的em,css3中又引入rem,兩者很容易混淆,所以在了解rem之前,需要先理清em的概念。

em作為font-size的單位時,其代表父元素的字體大小,em作為其他屬性單位時,代表自身字體大小。

通過以下實例可以很清晰的解讀em的內(nèi)涵:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<style type="text/css">
    .p1 {font-size: 16px; line-height: 32px;}
    .s1 {font-size: 2em;}
    .s2 {font-size: 2em; line-height: 2em;}

    .p2 {font-size: 16px; line-height: 2;}
    .s5 {font-size: 2em;}
    .s6 {font-size: 2em; line-height: 2em;}
</style>
<body>
    <div class="p1">
        <div class="s1">1</div>
        <div class="s2">1</div>
    </div>
    <div class="p2">
        <div class="s5">1</div>
        <div class="s6">1</div>
    </div>
</body>
</html>

在上面的實例中,在頁面最終的結(jié)果
s1:font-size:32px,line-height:32px;
s2:font-size:32px,line-height:64px;
s5:font-size:32px,line-height:64px;
s6:font-size:32px,line-height:64px
通過em可以看出改動父元素的字體大小,子元素會等比例變化。em可以讓頁面更靈活,更健壯,比起到處寫死的px值,em似乎更有張力。
基于em的這一特點,理論上是可以用em來做彈性布局頁面,但其復(fù)雜的計算讓人詬病,有人專門做了個px和em的轉(zhuǎn)換表,不同節(jié)點像素值對應(yīng)的em值,如下:


px和em的轉(zhuǎn)換表

更重要的問題在于如果rem做彈性布局的缺點,牽一發(fā)而動全身,一旦某個節(jié)點的字體大小發(fā)生變化,那么其后代元素都需要重新計算,這樣帶來的工作量無疑是繁瑣的。

對rem的理解

rem作用于非根元素時,相對于根元素字體大?。籸em作用于根元素字體大小時,相對于其出初始字體大小。

rem取值分為兩種情況,設(shè)置在根元素時和非根元素時

/* 作用于根元素,相對于原始大?。?6px),所以html的font-size為32px*/
html {font-size: 2rem}

/* 作用于非根元素,相對于根元素字體大小,這里的根元素的字體大小為32px,所以p標(biāo)簽的字體大小為64px */
p {font-size: 2rem}

em和rem各有優(yōu)點
對于em來說,可以認(rèn)為em是為字體和行高而生的,有些時候子元素字體就應(yīng)該相對于父元素,元素行高就應(yīng)該相對于字體大小。
對于rem來說,可以基于rem來建立一個同一參考系的概念。

Rem布局原理

rem布局的本質(zhì)是等比縮放,一般是基于寬度。
想象將屏幕寬度平均分成100份,每一份的寬度用x表示,x = 屏幕寬度 / 100,如果將x作為單位,x前面的數(shù)值就代表屏幕寬度的百分比,一個元素寬度為50x,那么該元素實際就占到了屏幕寬度的一半。基于這個理念,在css中,可以通過rem這個橋梁,實現(xiàn)頁面元素隨著屏幕寬度來進(jìn)行等比變化。

html {font-size: 16px}
p {width: 2rem} /* 32px*/

html {font-size: 32px}
p {width: 2rem} /*64px*/

如上,如果子元素設(shè)置rem單位的屬性,通過更改html元素的字體大小,就可以讓子元素實際大小發(fā)生變化。
如果讓html元素字體的大小,恒等于屏幕寬度的1/100,那么計算起來會更方便一些,比如此時html根元素大小為75,頁面一個元素的10rem,那么該元素的實際寬度就是75*10=750px;
通常通過js讓html根元素字體大小一直等于屏幕寬度的百分之一,一般需要在頁面dom ready、resize和屏幕旋轉(zhuǎn)中設(shè)置

document.documentElement.style.fontSize = document.documentElement.clientWidth / 100 + 'px';

如何把設(shè)計稿圖中的元素像素單位的值,轉(zhuǎn)換為已rem為單位的值?

假設(shè)設(shè)計圖寬度為a,根元素大小為f,將來設(shè)計圖是要完全鋪滿頁面的,那么根據(jù)以上,可以得知 f=a/100;
假設(shè)設(shè)計稿有一個元素的像素寬度為b,其對應(yīng)的rem的值為R,那么存在以下關(guān)系:
b=Rf=R(a/100)=>R=b/(a/100)=(b/a)100
元素的rem的值 = 元素寬度 / UE圖寬度 * 100
假設(shè)UE圖尺寸是640px,UE圖中的一個元素寬度是100px,根據(jù)公式100/640
100 = 15.625,元素的寬度為15.625rem。
可以通過以下的圖標(biāo)來驗證上面的論述是正確的。


UE圖寬度和屏幕寬度相同時,可以看出兩邊得出的元素寬度是一致的。

所以,在使用rem原理來布局的話,根據(jù)實際元素的像素,計算出對應(yīng)的rem值,就可以做到頁面的伸縮布局布局了。

但是,如果每個元素的寬高,以及位置,從像素單位轉(zhuǎn)化為對應(yīng)的rem值時,都需要計算,又會顯得很繁瑣,這里可以借用其他的方式實現(xiàn)免掉計算這一過程,布局時直接寫px,后期頁面渲染時通過某種方式來直接將px轉(zhuǎn)化為rem。

1、 可以通過預(yù)處理的function來簡化過程,比如使用sass

$ue-width: 640; /* ue圖的寬度 */

@function px2rem($px) {
  @return #{$px/$ue-width*100}rem;
}

p {
  width: px2rem(100);
}

上面的代碼編譯完的結(jié)果如下

p {width: 15.625rem}

2、使用相關(guān)插件cssrem,將CSS的 px 值直接轉(zhuǎn)為 rem 值

效果如下


cssrem
在sublime中安裝和配置cssrem插件的詳情參照如下:

安裝

  • 下載本項目,比如:git clone https://github.com/flashlizi/cssrem
  • 進(jìn)入packages目錄:Sublime Text -> Preferences -> Browse Packages...
  • 復(fù)制下載的cssrem目錄到剛才的packges目錄里。
  • 重啟Sublime Text。

配置參數(shù)

參數(shù)配置文件:Sublime Text -> Preferences -> Package Settings -> cssrem

  • px_to_rem - px轉(zhuǎn)rem的單位比例,默認(rèn)為40。
  • max_rem_fraction_length - px轉(zhuǎn)rem的小數(shù)部分的最大長度。默認(rèn)為6。
  • available_file_types - 啟用此插件的文件類型。默認(rèn)為:[".css", ".less", ".sass"]。

VScode cssrem插件使用 詳細(xì)教程

3、 此外還可以使用postcss來處理

p {width: 100px2rem}

postcss會對px2rem這個單位進(jìn)行處理,處理后的結(jié)果如下

p {width: 15.625rem}

可參考:
postcss-pxtorem:移動端px自動轉(zhuǎn)為rem

可參考的其他相關(guān)內(nèi)容:

1、 從網(wǎng)易與淘寶的font-size思考前端設(shè)計稿與工作流

2、高清顯示屏原理以及設(shè)計方案

3、移動web適配之rem

4、設(shè)備像素比devicePixelRatio簡單介紹

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容