跳至主要內容

px、rem、vh 到底該用哪個?企業官網 CSS 單位選擇完全指南

Diagram showing CSS units (px, rem, em, vh, vw, %) on different devices, highlighting responsive vs. fixed behavior.

工程師回報說:「桌機版都正常啊,我不知道手機為什麼會跑版。」

你打開 Chrome DevTools 切到手機模式一看——容器超出螢幕寬度、文字小到看不見、全螢幕的 Hero 區塊底部被瀏覽器網址列吃掉一截。

問題不在 media query 沒寫,而是那些「看起來沒問題但其實有問題」的 CSS 寫法。特別是 CSS 單位選錯,一行 `width: 960px` 就能讓整個手機版爆掉。

上一篇我們聊了設計端的 RWD 地雷,這篇來看實作面:CSS 單位到底該怎麼選,哪些寫法會讓版面炸掉,以及怎麼用現代 CSS 少寫一堆 media query。


📏 CSS 單位,選錯就炸

CSS 的長度單位有十幾種,但企業官網會用到的大概就這幾個。問題是,每個單位的行為不一樣,用錯地方就會出事。

px(像素) 是絕對單位,1px 就是 1px,不會因為螢幕大小或使用者設定而改變。適合用在 border、box-shadow、極小的裝飾性間距這類「不需要隨螢幕縮放」的地方。但如果你用 px 設定字體大小,使用者在瀏覽器調整預設字體大小時,你的字就不會跟著放大——這直接違反 WCAG 1.4.4 的無障礙規範。

rem 是相對於根元素(“)的字體大小。瀏覽器預設 `1rem = 16px`,但使用者可以自己調。Josh W. Comeau 在他的分析中說得很清楚:字體大小和間距用 rem,瀏覽器的無障礙縮放才能正常運作。Tailwind CSS 把所有字體大小都用 rem 定義,也是基於這個理由。

em 比較特別,它的參照對象會隨屬性不同而改變。用在 `font-size` 上,em 是相對於父元素的字體大小;但用在 `padding`、`margin` 這些屬性上,em 是相對於元素自身的字體大小。這個差異很重要,也是 em 好用的地方——按鈕的 padding 用 em,字體放大時 padding 會自動跟著放大,比例永遠協調。但 em 的字體大小會層層繼承,外層 `1.2em` 加內層 `1.2em` 就變成 `1.44em`,容易失控,所以字體大小建議用 rem 比較安全。

%(百分比) 通常相對於父元素的對應屬性。寬度百分比相對於父元素寬度,直覺好懂。但這裡有個經典陷阱:`padding-top` 和 `padding-bottom` 的百分比是相對於父元素的寬度,不是高度。很多人第一次遇到這個行為都會覺得是 bug,但其實是 CSS 規範就這樣定義的。

vw / vh 是相對於 viewport(可視區域)的單位。`100vw = 螢幕寬度`、`100vh = 螢幕高度`。看起來很直覺對吧?但 100vh 在手機上有個臭名昭彰的問題,我們等下專門講。

CSS unit decision tree infographic recommending rem for font size, em for internal spacing, percentage for borders/shadows, vw/vh for full screen, and clamp() for fluid typography.
這張 CSS 單位選擇速查表,清晰呈現了不同情境下應選用的 CSS 單位。從字體、間距到全螢幕版面,都能幫助您快速做出正確判斷。

簡單整理一下選擇原則:

用途建議單位原因
字體大小rem無障礙縮放正常運作
間距(margin / padding)rem跟隨使用者偏好縮放
元件內部間距em跟隨元件本身的字體大小
容器寬度% 或 max-width流動佈局的基礎
邊框、陰影px不需要縮放
全螢幕區塊dvh(不是 vh)避免手機網址列問題
流動字體clamp()一行搞定所有尺寸

💣 7 個讓版面炸掉的 CSS 寫法

接下來是實戰。這 7 個寫法,我們在接手企業官網維護時幾乎每次都會看到:

1. `width: 960px` — 固定寬度容器

手機螢幕寬度通常是 375px。你塞了一個 960px 寬的容器進去,直接超出螢幕 585px,水平捲動條就出現了。

/* ❌ 錯誤 */
.container { width: 960px; }

/* ✅ 正確 */
.container { width: 100%; max-width: 960px; margin: 0 auto; }

加上 `max-width` 和 `width: 100%`,容器在大螢幕維持 960px,小螢幕自動縮到螢幕寬度。一行就解決。

2. `height: 500px` — 固定高度容器

設計稿上那個 500px 高的區塊,在桌機上內容剛好放得下。但行動版的文字換行更多、內容更長,500px 根本塞不下,文字就溢出去了。或者更慘,搭配 `overflow: hidden` 直接把超出的內容砍掉,使用者根本不知道下面還有東西。

/* ❌ 錯誤 */
.hero { height: 500px; overflow: hidden; }

/* ✅ 正確 */
.hero { min-height: 500px; }

用 `min-height` 取代 `height`,內容少的時候維持最低高度,內容多的時候自動撐開。

3. `flex-shrink: 0` 全部子元素都不縮

Flexbox 預設會讓子元素在空間不足時自動縮小,這是 RWD 的好幫手。但有些工程師為了「防止元素被壓縮」,在每個子元素上都加 `flex-shrink: 0`。結果就是子元素的總寬度超過容器,直接溢出。

只在真正不能被壓縮的元素上用 `flex-shrink: 0`(例如一個固定寬度的 icon),其他元素讓它自然縮放。

4. CSS Grid 的 `1fr` 陷阱

Grid 的 `1fr` 表示「剩餘空間的一份」,但如果格子裡的內容(例如一張超寬圖片或一段不換行的程式碼)比 `1fr` 算出來的寬度還大,格子就會被撐開,整個 grid 爆掉。

/* ❌ 可能溢出 */
.grid { display: grid; grid-template-columns: 1fr 1fr; }

/* ✅ 限制最小寬度為 0 */
.grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }

Ahmad Shadeed 在他的 Defensive CSS 系列文章裡特別提過這個問題。加上 `minmax(0, 1fr)` 就能讓格子在內容過長時正確縮小。

5. `white-space: nowrap` 忘了處理溢出

有時候我們不希望文字換行(例如標籤、按鈕文字),用了 `white-space: nowrap`。但如果沒有搭配 `overflow` 和 `text-overflow` 處理,文字在小螢幕上就會直接衝出容器。

/* ✅ nowrap 要搭配溢出處理 */
.tag {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

6. `position: absolute` 在不同螢幕飄移

Absolute 定位的元素位置是相對於最近的 `position: relative` 祖先。桌機上看起來對齊了,但換到不同螢幕寬度,因為參考點不同,元素就飄到奇怪的位置。現代 CSS 有 Flexbox 和 Grid,大部分以前需要 absolute 定位的場景都能用更彈性的方式處理。

7. 過大的 `margin` / `padding` 用 px

桌機上 `padding: 80px` 的留白很舒服,但在 375px 寬的手機上,左右各 80px 就佔掉了 160px,內容只剩 215px 的寬度。

/* ❌ 錯誤 */
.section { padding: 80px; }

/* ✅ 用 clamp 做流動間距 */
.section { padding: clamp(1.5rem, 5vw, 5rem); }

📱 100vh 的經典坑

這個問題值得單獨拿出來講,因為太多人踩過了。

你寫了 `height: 100vh`,想讓一個區塊佔滿整個螢幕。桌機上完美。但手機上打開一看,底部被瀏覽器的網址列擋住了一截,或者往下滑一點網址列收起來之後,畫面突然跳動。

原因是:行動瀏覽器的網址列會在你往下滑的時候自動收合,可視區域高度會動態改變。但 `100vh` 被定義為「最大可視高度」(也就是網址列收合後的高度),所以在網址列展開時,`100vh` 其實比實際可視區域還要高。

這個行為在 2015 年由 Safari/WebKit 率先引入,Chrome 在 2016 年跟進,至今仍然維持不變。前端社群抱怨了好幾年,但瀏覽器廠商的態度就是不改。

Comparison of 100vh behavior on mobile. Left: expected full screen (svh). Right: actual result (dvh, lvh) with browser UI affecting viewport.
圖中說明了行動裝置上 100vh 單位可能遇到的問題:瀏覽器動態 UI 會影響實際可視區域。為此,CSS 引入了 svh、lvh 和 dvh 等新視窗單位,以更精確地應對手機版全螢幕顯示的挑戰。

好消息是,CSS 後來新增了三個 viewport 單位來解決這個問題:

  • `svh`(Small Viewport Height):網址列展開時的高度
  • `lvh`(Large Viewport Height):網址列收合後的高度(等於舊的 vh)
  • `dvh`(Dynamic Viewport Height):會跟著網址列的展開/收合動態改變

大部分場景用 `dvh` 就對了。瀏覽器支援度在 2025 年已經沒問題:Chrome 108+、Firefox 101+、Safari 15.4+、Edge 108+,根據 Can I Use 的資料,全球支援率超過 93%。

/* ❌ 手機上會出問題 */
.hero { height: 100vh; }

/* ✅ 用 dvh,搭配 vh 作為 fallback */
.hero { height: 100vh; height: 100dvh; }

寫兩行就好。不支援 dvh 的舊瀏覽器會吃第一行的 vh,新瀏覽器會用第二行的 dvh 覆蓋。


🔧 現代 CSS 函數,少寫 media query

以前做 RWD 要寫一堆 media query 來處理不同螢幕的字體大小和間距。現在有 `clamp()`、`min()`、`max()` 這幾個 CSS 函數,可以用一行解決。

`clamp(最小值, 偏好值, 最大值)` 是最實用的。它的意思是:「值不會小於最小值,不會大於最大值,中間按偏好值計算。」

/* 流動字體:手機最小 1rem,桌機最大 1.25rem,中間流暢過渡 */
h2 { font-size: clamp(1rem, 0.5vw + 0.875rem, 1.25rem); }

/* 流動間距:手機最小 1.5rem,桌機最大 5rem */
.section { padding: clamp(1.5rem, 5vw, 5rem); }

再來是 `min()`,很適合用在容器寬度:

/* 容器寬度不超過 1200px,但在小螢幕佔 90% 寬度 */
.container { width: min(90%, 1200px); margin: 0 auto; }

這一行就取代了原本需要分開寫 `max-width` 和 `width` 的做法(`margin: 0 auto` 還是要保留來置中)。

另外值得關注的是 Container Queries。傳統 media query 是根據「螢幕寬度」來調整樣式,但 Container Queries 讓元件可以根據「父容器的寬度」來調整。同一個卡片元件放在寬的主內容區是水平排列,放在窄的側邊欄就自動變垂直堆疊。瀏覽器支援率已經到 93.92%,可以開始用了。


✅ RWD CSS 自我檢測清單

最後給你一份快速檢查清單。打開你官網的 CSS,逐項看一下:

  • 有沒有用固定 px 設定容器寬度?(改用 max-width + 百分比)
  • 有沒有用固定 px 設定高度?(改用 min-height)
  • 字體大小是用 px 還是 rem?(改用 rem 或 clamp)
  • 有沒有用 100vh?(改用 100dvh)
  • 圖片有沒有加 `max-width: 100%`?(沒加的話圖片會超出容器)
  • 有沒有 `flex-shrink: 0` 造成溢出?
  • 有沒有 `white-space: nowrap` 沒搭配溢出處理?

如果以上有 3 項以上中獎,你的手機版八成有肉眼可見的問題。用 Chrome DevTools 的 Device Toolbar(按 Ctrl+Shift+M)切到手機模式跑一遍,很多問題一看就知道。

RWD 做對了,不需要什麼魔法。設計端想清楚、CSS 單位選對、避開這些已知的坑,手機版就不會再讓你開會時尷尬了。

有網站 RWD 相關的問題,歡迎聯絡我們,讓我們一起把你的官網手機版救回來。


  1. The Surprising Truth About Pixels and Accessibility – Josh W. Comeau, 2024
  2. CSS Values and Units – MDN Web Docs
  3. The Large, Small, and Dynamic Viewport Units – web.dev, 2023
  4. New Viewport Units – Ahmad Shadeed, 2023
  5. Defensive CSS – Ahmad Shadeed
  6. Preventing a Grid Blowout – CSS-Tricks
  7. Practical Uses of CSS Math Functions – Modern CSS
  8. Viewport Unit Variants Browser Support – Can I Use
  9. Tailwind CSS Font Size – Tailwind CSS Docs
  10. WCAG 1.4.4: Resize Text – W3C, 2023
  11. Container Queries in 2026 – LogRocket, 2026

註:所有數據與引述均截至 2026-03-17

網頁設計公司需要 ISO 27001?CTK Pro 的資安實踐之路
Previous Article

網頁設計公司需要 ISO 27001?CTK Pro 的資安實踐之路

ISO 27001 之災害復原:預防勝於治療
Next Article

ISO 27001 之災害復原:預防勝於治療

訂閱我們的文章

我們會不定期分享實用的網站經營技巧、真實客戶案例分析、最新數位趨勢觀察, 免費訂閱,讓靈感與成長不再錯過每一刻!
加入我們,一起用靈感點亮你的下一個專案 ✨