【CSS】CSS 單位指南與應用大全(em, rem, vh, vw, %, px, vmin, vmax)

閱讀時間約 12 分鐘
CSS 單位指南大全

CSS 單位指南大全

每一次在設定 CSS 時,單位總是在設定過程中,扮演了非常重要的角色。最近在補強 CSS 基礎的過程中,就將常見的單位應用整理出來。也提供實際應用的情境,希望讓讀者在處理各種 CSS 的單位時,不再有選擇困難。

對讀者來說,或許你已經聽說過像是「px」、「em」、「rem」、「vh/vw」以及 % 這些單位;但每一個單位,其實都有其潛在的設定與規則。接下來,筆者會深入探討這些單位的應用情境,以及如何選出合適的單位。

這一篇文章,會分成三個部分。分別是:

  1. 單位的基礎介紹
  2. 各單位的定義說明
  3. 各單位的應用情境、用法

就讓我們,開始探索吧!



一、單位的基礎介紹

基本單位可分成四個類別,分別是絕對長度、視圖長度、相對長度、比例長度

  • Absolute Length: 長度固定,無法被使用者調整。如 pxcm... 等。不要使用 cm 等單位,會因為銀幕解析度的差異,而導致長度不固定。
  • Viewport Length: 長度跟隨瀏覽器視窗而調整,包含 vhvwvminvmax 等單位。
  • Relative Length: 會隨著使用者的習慣調整,包含 remem 等,其他的鮮少用到。
  • Percentage Length: 特殊的比例長度,可能會隨著 viewport 或容器大小調整。

那你有想過,為什麼需要這麼多的單位嗎?

其實,主要是為了 Accessibility 的作用。因為有時要提供給一些特殊需求的使用者,或是為了滿足放大或縮小文字的特定使用。因此,需要讓他們有機會可以放大文字,但同時仍能控制排版。


哪一些屬性,可以使用這一些單位?

基本上圍繞在 Box-model 和定位上,font-size、padding、border、margin、width、height、top、bottom、left、right 都可以適用。通常瀏覽器預設的 1rem 都是 16px (font-size: 16px)。


為什麼需要可調整的單位?

Chrome Setting

Chrome Setting

因為使用者可能會調整瀏覽器的文字大小,我們希望可以隨著使用者設定的大小,來相對應調整。若使用固定如 20px 的大小,則文字不會根據瀏覽器設定,調整大小。




二、各單位的定義說明

接著,就來說明常見的單位,各自的定義是有哪些?

  1. Absolute Length - px
  2. Viewport Length - vh/vw
  3. Relative Length - em/rem
  4. Percentage Length - %



I. Absolute Length - px

.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 來簡化狀況。



II. Viewport Length - vh/vw/vmin/vmax

.selector {
width: 100vw; // 100% viewport width
height: 100vh; // 100% viewport height
}


vh 和 vw 的定義
vhvw 分別指的是 viewport height 和 viewport width,換句話說,指的是瀏覽器的視窗(viewport)實際的寬度。使用 vh 和 vw 的好處,是可以省掉設定 height:100% 或 width: 100%,不一定會填滿視窗寬度的問題。

vmin 和 vmax 的定義
vminvmax 兩者的差異,在於 min 指的是 vw 和 vh 中較小的一邊;max 則是 vm 和 vh 中較大的一邊。舉例來說,1280px * 1600px 的長寬視窗比,vmin 指的就是 1280px;vmax 則是 1600px。而設定的則是比率,例如 120vmin 指的是 1280px * 120% 的意思;而 80vmax 指的是 1600px * 80% 的意思。

可以用來限制在特定長度或寬度下,可以達成 RWD 的效果。



III. Relative Length - em/rem

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。



IV. Percentage Length - %

要理解 % 的概念,就需要先理解 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 的狀態。



三、各單位的應用情境、用法

了解各個常見的單位後,就可以來了解不同情境下,可以如何應用上述所學到的單位。

  1. 對於文字尺寸的設定 Font-size
  2. 對於 Background 的長寬設定



I. 對於文字尺寸的設定 Font-size

因為瀏覽器本身可以設定文字基礎大小,若使用 px 固定大小則會無法自動調整。因此可以使用:

  • rem: 會根據瀏覽器在 html 的字體大小設定,乘以特定的比率來顯示。例如 1 rem 指的是預設 16px * 1 大小的字。通常建議使用此設定。
  • xx%:設定 70%,則會以瀏覽器的文字大小 * 70% 作為文字顯示,但不建議使用。
  • em: 會根據父元素的大小,去乘以設定的比率。例如父元素為 1.5em,則子元素設定為 1.5em 則會顯示 16px * 1.5 * 1.5 的文字大小。建議使用在特定相依區域,不然大小很容易失控。
  • not setting: 或是就根據瀏覽器預設尺寸,來設定。


II. 對於 Background 的長寬設定

對於背景的長寬設定,通常建議可以使用 vh 和 vw 來設定,使之可以根據銀幕大小動態調整。除非有長寬比會隨視窗調換的情境,才會使用 vmin 和 vmax。


III. Box-model 與 Position 的設定

常見的應用情境如下:

  • padding/margin: Only apply rem
  • borderpx (Usually not change)
  • widthx% or vw/vh (which is better depends on the situation)
  • top/buttom/left/rightx% (depend on containing block)


III. 寬度在 Windows 上的 Bug

https://bit.ly/3OkudIq

因為 Windows 如果使用 vw 會自動出現滾動條,為了避免可以使用 width: 100% 來代替。另一個方式,則是使用在 body 加上 overflow-x: hidden;。如果是縱向的捲軸,則可加上  overflow-y: hidden 來解決。


結論:CSS 單位

本文介紹了常見的 CSS 長度單位,包括絕對長度、相對長度、百分比長度以及 viewport 長度。其中,推薦使用相對長度 rem 和 em,以及 viewport 長度 vh 和 vw。此外,本文還介紹了不同情境下各單位的應用方法,包括文字尺寸的設定、背景的長寬設定以及 Box-model 與 Position 的設定。

CSS 之所以難學習,是因為多數時候他並沒有一定的邏輯,而是根據 W3C 的設定而來。這就導致 CSS 很單純靠理解來學習。因此,非常建議在一邊學習的同時,一定要一邊練習,讓眼睛能夠看到,才能夠了解 CSS 實際的變化為何。



延伸閱讀

技術文章

學習成長



Reference

此處作為整理前端(Frontend)和相關的 HTML、CSS、JavaScript、React 等前端觀念與技巧,全部都會收錄在這個專題之中。同時也會將相關的技術與反思記錄在此,歡迎各位讀者互相交流。
留言0
查看全部
發表第一個留言支持創作者!
在 React 測試生態系統中,React Testing Library 成為了方便好用的選擇,因其強調測試應該關注於使用者的操作與觀察元件行為,而不是測試細節實現。
在軟體領域中,"Thunk" 是一個常用的術語,它指的是一種用於延遲計算,或將運算延後執行的程式碼片段。它通常用於函數式編程,或編譯器的設計中。Redux 透過 createAsyncThunk 實作了該非同步/異步操作,並提供數個 API 協助我們使用 Redux。
React 表單驗證是一種技術與使用者體驗的設計,讓使用者能夠即時檢查輸入的資料並修正,提升使用者的使用體驗,並確保資料的正確性。
useContext 是一種 React hook,讓我們能夠直接取用其他元件的 Context,而無須層層傳遞 props,進而使程式碼簡潔易讀。
在傳統開發的過程中,很容易會搞混一般的 this 和箭頭函式(arrow function)中的 lexcial "this" 兩者的差異。本文就以實際的例子來說明各自的差異,以及在未來使用時需要注意哪一些細節。
在 React 測試生態系統中,React Testing Library 成為了方便好用的選擇,因其強調測試應該關注於使用者的操作與觀察元件行為,而不是測試細節實現。
在軟體領域中,"Thunk" 是一個常用的術語,它指的是一種用於延遲計算,或將運算延後執行的程式碼片段。它通常用於函數式編程,或編譯器的設計中。Redux 透過 createAsyncThunk 實作了該非同步/異步操作,並提供數個 API 協助我們使用 Redux。
React 表單驗證是一種技術與使用者體驗的設計,讓使用者能夠即時檢查輸入的資料並修正,提升使用者的使用體驗,並確保資料的正確性。
useContext 是一種 React hook,讓我們能夠直接取用其他元件的 Context,而無須層層傳遞 props,進而使程式碼簡潔易讀。
在傳統開發的過程中,很容易會搞混一般的 this 和箭頭函式(arrow function)中的 lexcial "this" 兩者的差異。本文就以實際的例子來說明各自的差異,以及在未來使用時需要注意哪一些細節。
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
  製作校長盃 UI 設計首獎作品:實作元件切版過程中因為不夠了解Position的屬性而造成在對content內容排版一直跑掉,一開始想都使用Position來實作所有的排版,但是Position的absolute與fixed屬性在使用時元件將不再佔有一排,而下面的元件會自動向上遞補,就造成了排版
Thumbnail
這是一篇關於 CSS 動畫屬性的學習筆記,如果你剛好也在學習的話,歡迎進來看看!
Thumbnail
不論是在基礎或是進階的版面排列,幾乎離開不了 position 系列的 CSS 語法,如果對於這些語法不熟悉,要快速完成畫面需求幾乎是不可能的,甚至會延宕整個團隊的開發速度(對,position 語法就是這麽重要)。
Thumbnail
source code: E 提供兩個範例,其實before, after就如同字面上的意思,會在前後加上內容。 範例1簡單的在前後加上文字,如下所示,需特別注意,是在div內的範例1前後加上文字。 before/after除了可以加上文字以外,還可以作為裝飾效果。如範例2,利用position調
Thumbnail
css display grid可以達到類似table span的排版效果,但還是有些差異,table的span其實是合併,css grid比較像是要佔幾格的意思。 如下程式碼為例,colspan是要往右合併的意思,因此會少一個td。 E css grid colspan sample code:
筆記一下,原本寫成overflow-y: auto,在windows chrome瀏覽器有y scroll bar,唯獨iPad沒有scroll bar,解法如下: overflow-y: scroll; -webkit-overflow-scrolling: touch; 本筆記參考: 1. h
Thumbnail
對於前端初學者來說,在切版時會出現很多規則、不規則的網頁區塊,這時候我們會嘗試用各種相對定位、絕對定位、margin 或是 padding 的方式來進行網頁區塊的推擠。
Thumbnail
明明想要某個欄位的寬高為 200px,卻發現自己不知道為什麼怎麼更改都會改不動,又或者寬高更改了,卻沒有辦法與其他元素並列。 上述的狀況,通常都是在不熟悉 HTML display 特性而產生的狀況下才會出現⋯⋯
Thumbnail
有時我們會在CSS裡看到「>」、「+」、「~」這些符號的使用,它們到底有甚麼功用呢?  A.大於符號(>) 大於(>)就是選取底下直接的子元素。 以大於符號(.box > p)和空格(.box p)來做比較,先看以下例子: 使用空格的情況 .box p{ font-size:20px; color
Thumbnail
CSS提供許多選擇器類型,當使用不同的選擇器時,套用樣式的優先權也會不同。 A.元素內的(行內)樣式>頁面內的(崁入)樣式>外部載入(串連) 元素內的(行內)樣式 例子: 頁面內的樣式(崁入樣式) 例子: 外部載入(串連) 例子: B.後設定>前設定 最後設定的樣式將蓋過之前設定的樣式 例子:
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
  製作校長盃 UI 設計首獎作品:實作元件切版過程中因為不夠了解Position的屬性而造成在對content內容排版一直跑掉,一開始想都使用Position來實作所有的排版,但是Position的absolute與fixed屬性在使用時元件將不再佔有一排,而下面的元件會自動向上遞補,就造成了排版
Thumbnail
這是一篇關於 CSS 動畫屬性的學習筆記,如果你剛好也在學習的話,歡迎進來看看!
Thumbnail
不論是在基礎或是進階的版面排列,幾乎離開不了 position 系列的 CSS 語法,如果對於這些語法不熟悉,要快速完成畫面需求幾乎是不可能的,甚至會延宕整個團隊的開發速度(對,position 語法就是這麽重要)。
Thumbnail
source code: E 提供兩個範例,其實before, after就如同字面上的意思,會在前後加上內容。 範例1簡單的在前後加上文字,如下所示,需特別注意,是在div內的範例1前後加上文字。 before/after除了可以加上文字以外,還可以作為裝飾效果。如範例2,利用position調
Thumbnail
css display grid可以達到類似table span的排版效果,但還是有些差異,table的span其實是合併,css grid比較像是要佔幾格的意思。 如下程式碼為例,colspan是要往右合併的意思,因此會少一個td。 E css grid colspan sample code:
筆記一下,原本寫成overflow-y: auto,在windows chrome瀏覽器有y scroll bar,唯獨iPad沒有scroll bar,解法如下: overflow-y: scroll; -webkit-overflow-scrolling: touch; 本筆記參考: 1. h
Thumbnail
對於前端初學者來說,在切版時會出現很多規則、不規則的網頁區塊,這時候我們會嘗試用各種相對定位、絕對定位、margin 或是 padding 的方式來進行網頁區塊的推擠。
Thumbnail
明明想要某個欄位的寬高為 200px,卻發現自己不知道為什麼怎麼更改都會改不動,又或者寬高更改了,卻沒有辦法與其他元素並列。 上述的狀況,通常都是在不熟悉 HTML display 特性而產生的狀況下才會出現⋯⋯
Thumbnail
有時我們會在CSS裡看到「>」、「+」、「~」這些符號的使用,它們到底有甚麼功用呢?  A.大於符號(>) 大於(>)就是選取底下直接的子元素。 以大於符號(.box > p)和空格(.box p)來做比較,先看以下例子: 使用空格的情況 .box p{ font-size:20px; color
Thumbnail
CSS提供許多選擇器類型,當使用不同的選擇器時,套用樣式的優先權也會不同。 A.元素內的(行內)樣式>頁面內的(崁入)樣式>外部載入(串連) 元素內的(行內)樣式 例子: 頁面內的樣式(崁入樣式) 例子: 外部載入(串連) 例子: B.後設定>前設定 最後設定的樣式將蓋過之前設定的樣式 例子: