每一次在設定 CSS 時,單位總是在設定過程中,扮演了非常重要的角色。最近在補強 CSS 基礎的過程中,就將常見的單位應用整理出來。也提供實際應用的情境,希望讓讀者在處理各種 CSS 的單位時,不再有選擇困難。
對讀者來說,或許你已經聽說過像是「px」、「em」、「rem」、「vh/vw」以及 % 這些單位;但每一個單位,其實都有其潛在的設定與規則。接下來,筆者會深入探討這些單位的應用情境,以及如何選出合適的單位。
這一篇文章,會分成三個部分。分別是:
就讓我們,開始探索吧!
基本單位可分成四個類別,分別是絕對長度、視圖長度、相對長度、比例長度:
px
、cm
... 等。不要使用 cm 等單位,會因為銀幕解析度的差異,而導致長度不固定。vh
、vw
、vmin
、vmax
等單位。rem
、em
等,其他的鮮少用到。那你有想過,為什麼需要這麼多的單位嗎?
其實,主要是為了 Accessibility 的作用。因為有時要提供給一些特殊需求的使用者,或是為了滿足放大或縮小文字的特定使用。因此,需要讓他們有機會可以放大文字,但同時仍能控制排版。
基本上圍繞在 Box-model 和定位上,font-size、padding、border、margin、width、height、top、bottom、left、right 都可以適用。通常瀏覽器預設的 1rem 都是 16px (font-size: 16px
)。
因為使用者可能會調整瀏覽器的文字大小,我們希望可以隨著使用者設定的大小,來相對應調整。若使用固定如 20px 的大小,則文字不會根據瀏覽器設定,調整大小。
接著,就來說明常見的單位,各自的定義是有哪些?
px
vh/vw
em/rem
%
.selector {
width: 500px; // 500 像素大小
height: 100px; // 100 像素大小
}
絕對長度。指的是完全固定的長度或尺寸。在 CSS 中,1 像素被正式定義為 1/96 英吋。所有其他的絕對長度單位,都是基於這個像素的定義。例如 cm 或 mm 等。
其實除了常見的 px 之外,也有 inch、cm 等單位可以使用;但會有一個極大的問題,該單位的換算,僅基於一個邏輯計算,例如 1 inch = 96px。
實際上,我們的硬體像素,實際上和軟體像素不同。中間會有一個換算比率。例如 iPhone SE 的設備硬體解析素為 640 x 1136,但軟體解析度則是 320 x 568,轉換率為 2.0。如果採用 inch 等設定,就會導致實際寬度會與預期不符。因此只要是固定長度,一率使用 px 來簡化狀況。
.selector {
width: 100vw; // 100% viewport width
height: 100vh; // 100% viewport height
}
vh 和 vw 的定義vh
和 vw
分別指的是 viewport height 和 viewport width,換句話說,指的是瀏覽器的視窗(viewport)實際的寬度。使用 vh 和 vw 的好處,是可以省掉設定 height:100% 或 width: 100%,不一定會填滿視窗寬度的問題。
vmin 和 vmax 的定義vmin
和 vmax
兩者的差異,在於 min 指的是 vw 和 vh 中較小的一邊;max 則是 vm 和 vh 中較大的一邊。舉例來說,1280px * 1600px 的長寬視窗比,vmin 指的就是 1280px;vmax 則是 1600px。而設定的則是比率,例如 120vmin 指的是 1280px * 120% 的意思;而 80vmax 指的是 1600px * 80% 的意思。
可以用來限制在特定長度或寬度下,可以達成 RWD 的效果。
em 和 rem 是相對大小,後者指的是 root em,亦即僅會參考 root 的文字大小(亦即 body 的設定)。
em
:根據父元素的大小,去乘以設定的比率。例如瀏覽器預設文字為 16px,父元素為 1.5em,且子元素設定為 1.5em,則子元素的文字會顯示 16px * 1.5 * 1.5 的文字大小。rem
:推薦使用單位。僅會參考 body 或預設瀏覽器設定的大小,不會理會父元素的設定。因為統一的標準都是 root 元素,因此更容易管理與調整。因為現在瀏覽器的支援程度已經高達 96%,除非可能會用到 IE 舊版本的瀏覽器,不然通常都建議使用 em,作為相對單位的設定。而 em
僅建議使用在特定相依區域,不然大小很容易失控。因為我們不知道父元素是否有設定到 em。
要理解 % 的概念,就需要先理解 Containing block 的概念。意指對於某一個應用的元素來說,其參照的父元素就被稱為 containing block。
舉例來說,如果我有一個下列的元素。對於 div 來說,在 Nav 設定為 position: fixed
的情況下,瀏覽器的 viewport 就是 Nav 的 Containing block;如果設定 div 為 position: absolute
、 nav 設定為 position: relative
的情況下,nav 就是 div 的 containing block。
<nav>
<div />
</nav>
% 在不同 Position 的使用情境:
position: fixed
: 該元素會根據 viewport 作為參照,並根據設定的 x% 來調整大小。position: absolute
: 會根據 ancestor element 該 containing block 的 content
+ padding
空間來計算。而 ancestor element 指的是顯式設定非position: static
狀態的元素為主。此時,設定 width: 100%
就會以 ancestor 的寬度為主。position: static/relative
: 會根據 block level 的父元素,來作為衡量的標準。如果父元素為 inline,則寬度會維持最小內容寬度,但高度會塌陷至內容所需的高度。如何達成 100% 的瀏覽器 viewport 高度設定?
要從 html > body > ... > div 的目標元素,才有辦法讓 div 設定為 height: 100% 時,可以完全等於 100% 的 viewport。如果沒有設定 top: 0
/ left: 0
或 inset 等參數,則一樣會吃到 margin-collapse 的狀態。
了解各個常見的單位後,就可以來了解不同情境下,可以如何應用上述所學到的單位。
因為瀏覽器本身可以設定文字基礎大小,若使用 px 固定大小則會無法自動調整。因此可以使用:
rem
: 會根據瀏覽器在 html 的字體大小設定,乘以特定的比率來顯示。例如 1 rem
指的是預設 16px * 1 大小的字。通常建議使用此設定。xx%
:設定 70%
,則會以瀏覽器的文字大小 * 70% 作為文字顯示,但不建議使用。em
: 會根據父元素的大小,去乘以設定的比率。例如父元素為 1.5em,則子元素設定為 1.5em 則會顯示 16px * 1.5 * 1.5 的文字大小。建議使用在特定相依區域,不然大小很容易失控。not setting
: 或是就根據瀏覽器預設尺寸,來設定。對於背景的長寬設定,通常建議可以使用 vh 和 vw 來設定,使之可以根據銀幕大小動態調整。除非有長寬比會隨視窗調換的情境,才會使用 vmin 和 vmax。
常見的應用情境如下:
padding/margin
: Only apply rem
border
: px
(Usually not change)width
: x%
or vw/vh
(which is better depends on the situation)top/buttom/left/right
: x%
(depend on containing block)因為 Windows 如果使用 vw 會自動出現滾動條,為了避免可以使用 width: 100%
來代替。另一個方式,則是使用在 body
加上 overflow-x: hidden;
。如果是縱向的捲軸,則可加上 overflow-y: hidden
來解決。
本文介紹了常見的 CSS 長度單位,包括絕對長度、相對長度、百分比長度以及 viewport 長度。其中,推薦使用相對長度 rem 和 em,以及 viewport 長度 vh 和 vw。此外,本文還介紹了不同情境下各單位的應用方法,包括文字尺寸的設定、背景的長寬設定以及 Box-model 與 Position 的設定。
CSS 之所以難學習,是因為多數時候他並沒有一定的邏輯,而是根據 W3C 的設定而來。這就導致 CSS 很單純靠理解來學習。因此,非常建議在一邊學習的同時,一定要一邊練習,讓眼睛能夠看到,才能夠了解 CSS 實際的變化為何。