簡言
應用象EM
和 REM
這種相對長度單位進行頁面排版是WEB開發中的最佳實踐。在頁面排版中較好應用EM
和 REM
,根據裝置尺寸縮放顯示元素的大小。這就使得元件在不同裝置上都達到最佳的顯示效果成為可能。
但問題是究竟該用 EM
還是 REM
呢?關於這個問題一直存在比較大的爭議。本文將會給大家介紹究竟什麼是 EM
和 REM
和如何進行兩者的選擇,以及結合兩者優勢構建模組化的WEB元件。
注:本文內容簡單,只面向初級開發人員,約2500字,閱讀時間5分鐘。
1 什麼是EM?
em
是相對長度單位。它相對於當前元素字型尺寸,即font-size
。舉例來說,如果當前元素的字型是20px,那麼當前元素中的1em就等於20px。
h1 { font-size: 20px } /* 1em = 20px */
p { font-size: 16px } /* 1em = 16px */
複製程式碼
實際開發中,用相對長度單位(如 em
)表示字型大小是WEB開發中的最佳實踐。
考慮下面的程式碼:
h1 { font-size: 2em }
複製程式碼
這裡的h1元素字型大小究竟是多少呢?
這時,我們需要根據<h1>
父元素字型的大小,來計算<h1>
字型的尺寸大小。如果父元素是<html>
,而且<html>
的字型大小是16px。就可以計算出<h1>
的字型大小是32px,即2*16px。
用程式碼表示如下:
html { font-size: 16px }
h1 { font-size: 2em } /* 16px * 2 = 32px */
複製程式碼
設定<html>
字型的大小一般來說都不是一個好主意,因為這樣重寫了使用者瀏覽器的預設設定。相反,可以使用百分比值或者根本不宣告<html>
字型大小。
html { font-size: 100% } /* 預設 16px */
複製程式碼
對於大多數使用者或瀏覽器,字型預設大小是16px(未做瀏覽器預設字型尺寸設定)。
em
還能用來指定除字型大小外的其它屬性,象margin
或padding
等屬性都可以用em
來表示。
考慮下面的程式碼, 對於<h1>
和<p>
元素,margin-bottom
值應該是多少? (假設<html>
的字號被設定為100%)。
h1 {
font-size: 2em; /* 1em = 16px */
margin-bottom: 1em; /* 1em = 32px */
}
p {
font-size: 1em; /* 1em = 16px */
margin-bottom: 1em; /* 1em = 16px */
}
複製程式碼
上述<h1>
和<p>
的margin-bottom都是1em,但是外邊距結果值卻不相同。上述現象的出現,是因為em
是相對於當前元素字型的大小。由於<h1>
中的字型大小現在設定為2em, 因此<h1>
中其它屬性的1em值就是 1em = 32px
。這裡比較容易引起誤解的地方。
2 什麼是REM?
rem
表示 root em,它是相對於根元素的長度單位。這裡根元素就是<html>
中定義的字型大小。這意味著任何地方的1rem總是等於<html>
中定義的字型大小。
利用上述相同的程式碼,我們用 rem
來代替 em
,檢視margin-bottom
的計算值究竟是多少?
h1 {
font-size: 2rem;
margin-bottom: 1rem; /* 1rem = 16px */
}
p {
font-size: 1rem;
margin-bottom: 1rem; /* 1rem = 16px */
}
複製程式碼
如上述程式碼所示,1rem總是等於16px(除非變更了<html>
字型的大小)。rem
的大小相較於em
來說意義更直接明確,也很容易理解。
3 REM 還是 EM?
在專案開發中究竟是選用 rem
還是 em
一直以來爭議不斷。一些開發人員不使用rem
,因為rem
使元件不那麼模組化。而另一些開發人員喜歡rem
的簡單性,使用rem
處理所有元素。
其實 em
和rem
都有各自的優勢和劣勢,在實際專案開發中,應該結合使用兩者,利用各自的優勢,從而實現較好程式碼質量和顯示效果。
那麼在具體的應用中如何在兩者中做選擇呢?有兩條簡單的指導原則:
- 如果屬性尺寸要根據元素字型進行縮放,則使用
em
- 其它情況下都使用
rem
上述規則太簡單了。 為了更好的理解上述規則,我們就以一個簡單的header元件為例,說明單獨使用兩者來實現元件遇到的問題,並體會結合使用兩者所帶來的優勢。
3.1 只使用REM
這裡我們只使用rem
來編寫一個header元件,程式碼及執行結果如下:
.header {
font-size: 1rem;
padding: 0.5rem 0.75rem;
background: #7F7CFF;
}
複製程式碼
接下來,網站需要一個尺寸更大的header元件。
變更CSS程式碼如下:
.header {
font-size: 1rem;
padding: 0.5rem 0.75rem;
background: #7F7CFF;
}
.header-large {
font-size: 2rem;
}
複製程式碼
執行結果如下:
從上述執行結果可以看出,文字的內邊距(padding
)過小,顯示效果不協調。如果我們堅持只使用rem
,只能變更css程式碼如下:
.header {
font-size: 1rem;
padding: 0.5rem 0.75rem;
background: #7F7CFF;
}
.header-large {
font-size: 2rem;
padding: 1rem 1.5rem;
}
複製程式碼
變更後執行結果如下:
上述程式碼及執行結果,雖然達到了預期的顯示效果,但卻違背了程式碼複用的原則。如果網站有多種尺寸的.header樣式,就要多次重複的定義內邊距。重複的程式碼增加了專案複雜度,降低了可維護性。
這時可以利用em
可以變更上述程式碼如下:
.header {
font-size: 1rem;
padding: 0.5em 0.75em;
background: #7F7CFF;
}
.header-large {
font-size: 2rem;
}
複製程式碼
執行結果請檢視演示程式:
如上述演示程式所示,當元素屬性值的大小需要根據元素字型尺寸縮放時,就應該應用 em
來定義屬性尺寸。這就是前述規則中的第一條規則。
3.2 只使用EM
如果只使用em
來定義上述元件,結果會怎樣呢?
我們變更上述程式碼如下(em
替換rem
):
.header {
font-size: 1em;
padding: 0.5em 0.75em;
background: #7F7CFF;
}
.header-large {
font-size: 2em;
}
複製程式碼
為更接近實際,我們引入了<p>
元素,並變更html
程式碼如下:
<div class="header header-large">名人名言</div>
<p>簡單是穩定的前提</p>
<div class="header">名人名言</div>
<p>簡單是穩定的前提</p>
複製程式碼
增加p元素css程式碼如下:
p {
padding: 0.5em 0.75em;
}
複製程式碼
執行結果如下:
從上述執行經果中,不難看出.header-large
部分的標題並沒有和文字左對齊。而如果只使用em
實現左對齊,則需要變更CSS程式碼如下:
.header {
font-size: 1em;
padding: 0.5em 0.75em;
background: #7F7CFF;
}
.header-large {
font-size: 2em;
padding-left: 0.375em;
padding-right: 0.375em;
}
複製程式碼
變更後執行結果如下:
上述程式碼及執行結果,雖然達到了預期的顯示效果,但卻違背了程式碼複用的原則。如果網站有多種尺寸的.header樣式,就要多次重複的定義左右邊距。重複的程式碼增加了專案複雜度,降低了可維護性。
解決上述問題的辦法是結合使用em
和rem
,即使用em
定義上下邊距,使用rem
定義左右邊距。變更後程式碼如下:
.header {
padding: 0.5em 0.75rem;
font-size: 1em;
background: #7F7CFF;
}
.header-large {
font-size: 2em;
}
複製程式碼
執行結果請檢視演示程式:
3.3 EM還是REM總結
究竟是該使用em
還是rem
呢?答案應該是結合使用rem
和rem
。當屬性值的大小需要根據當前元素字型尺寸縮放時,就選用em
,其它的情況都使用更簡單的rem
。
4 em及rem值的設定
em
和rem
屬性值都要經過計算轉化成絕過長度單位。常用的字型尺寸用相對長度單位表示會很困難。看下面常用字型值的rem
表示(基本字型尺寸是16px):
- 10px = 0.625rem
- 12px = 0.75rem
- 14px = 0.875rem
- 16px = 1rem (base)
- 18px = 1.125rem
- 20px = 1.25rem
- 24px = 1.5rem
- 30px = 1.875rem
- 32px = 2rem
如上述列表所示,上述尺寸值的表示及計算都不分的不便。為了解決上述問題要用到一個小技巧,即著名的 "62.5%"技術。具體請檢視下述程式碼:
body { font-size:62.5%; } /* =10px */
h1 { font-size: 2.4em; } /* =24px */
p { font-size: 1.4em; } /* =14px */
複製程式碼
通過62.5%的設定,就可以很容易用em
來定義具體屬性的尺寸了(10倍的關係)。
而rem
,則需要採用如下的方式:
html { font-size: 62.5%; } /* =10px */
body { font-size: 1.4rem; } /* =14px */
h1 { font-size: 2.4rem; } /* =24px */
複製程式碼
5 響應式例子
一個簡單的響應式的例子,調整瀏覽器寬度檢視演示效果。
6 參考資料
- W3C:CSS Values and Units Module Level 3
- zellwk:REM vs EM – The Great Debate
- sitepoint:Understanding and Using rem Units in CSS
- tutsplus:Comprehensive Guide: When to Use Em vs. Rem
- css-tricks:Confused About REM and EM?
7 說明
文中所述文字及程式碼部分彙編於網路。因時間不足,能力有限等原因,存在文字闡述不準及程式碼測試不足等諸多問題。因此只限於學習範圍,不適用於實際應用。另em
和rem
在較老的瀏覽器中存在相容性問題。