現代 CSS clamp() 完整筆記
clamp() 常被稱為「媒體查詢殺手」,因為很多「只是字體、間距要跟著螢幕慢慢變大/變小」的情境,其實根本不需要一堆 @media,一行 clamp() 就能搞定。
1. 問題背景:為什麼會寫出 40+ 個媒體查詢?
典型情境:為了讓頁面在 375 / 768 / 1024 / 1440… 等尺寸都漂亮,你會寫:
h1 {
font-size: 24px;
} /* Mobile */
@media (min-width: 768px) {
h1 {
font-size: 32px;
} /* Tablet */
}
@media (min-width: 1024px) {
h1 {
font-size: 40px;
} /* Desktop */
}
@media (min-width: 1440px) {
h1 {
font-size: 48px;
} /* Large desktop */
}
一個標題就四個斷點、12 行 CSS;若所有標題、段落、按鈕、容器都這樣寫,很快就變成「媒體查詢地獄」,而且在 800px、1200px 這種「介於斷點之間」的寬度,字體會突然跳變,不夠流暢。
2. clamp() 是什麼?核心概念
語法:
property: clamp(min, preferred, max);
- min:最小值(數值不會小於它)
- preferred:首選值,通常會用
vw或vw + px,讓數值隨視窗寬度變化 - max:最大值(數值不會大於它)
瀏覽器會優先採用「首選值」,但若太小就用 min,太大就用 max。
/* 字體會在 24px ~ 48px 間,跟著視窗寬度線性縮放 */
font-size: clamp(24px, 5vw, 48px);
效果:
- 320px 手機:
5vw = 16px→ 被下限 24px clamp 起來 → 24px - 768px 平板:
5vw = 38.4px→ 落在 24–48 範圍 → 38.4px - 1920px 螢幕:
5vw = 96px→ 被上限 48px clamp → 48px
整段寬度之間會「平滑縮放」,不再是斷點跳變。
3. 實戰例子:用 clamp() 取代多數媒體查詢
3.1 響應式標題字體(Fluid Typography)
舊寫法:
h1 {
font-size: 28px;
}
@media (min-width: 640px) {
h1 {
font-size: 36px;
}
}
@media (min-width: 1024px) {
h1 {
font-size: 48px;
}
}
@media (min-width: 1440px) {
h1 {
font-size: 56px;
}
}
新寫法:
h1 {
font-size: clamp(28px, 4vw, 56px);
}
15 行變 3 行,且縮放更平滑。
3.2 容器內距 / 外距(Padding / Margin)
.container {
padding: clamp(16px, 4vw, 64px);
}
- 小螢幕時接近 16px
- 大螢幕時接近 64px
- 中間寬度則線性補間
3.3 卡片網格間距(Grid Gaps)
.grid {
gap: clamp(12px, 2vw, 32px);
}
小螢幕時卡片之間較緊,中大螢幕逐漸拉開。
3.4 其他很適合用 clamp() 的屬性
- 字體大小:
font-size - 內外距:
padding,margin - 寬度限制:
max-width - 卡片圓角:
border-radius - 元件高度:
height,min-height
4. 如何計算「首選值」的 vw?
如果想要更精準控制,可以用一個簡單公式來算中間那個 vw:
- 決定最小值 / 最大值
- 例如:字體最小 16px、最大 32px
- 決定對應的視窗寬度範圍
- 例如:375px(手機)到 1440px(桌機)
- 計算差值
- 尺寸差:
32 - 16 = 16px - 寬度差:
1440 - 375 = 1065px
- 尺寸差:
- 換成百分比
16 / 1065 ≒ 0.015 = 1.5%→ 就是 1.5vw
- 組合成
clamp()
font-size: clamp(16px, 1.5vw + 16px, 32px);
這樣可以保證在 375–1440px 這段範圍內,字體會從 16px 線性縮放到 32px。
懶人作法:直接從
2vw、3vw開始試,搭配 Clamp Calculator 之類工具微調就好。
5. 什麼時候「不要」用 clamp()?還是要媒體查詢
clamp() 解決的是「數值隨寬度平滑變化」的問題,但結構變化還是交給 @media:
-
佈局改變
-
例如從單欄 → 雙欄:
@media (min-width: 768px) {
.layout {
display: grid;
grid-template-columns: 1fr 1fr;
}
}
-
-
顯示 / 隱藏元素
@media (max-width: 767px) {
.desktop-only {
display: none;
}
} -
行為改變
- 例如桌機是完整導覽列,手機變漢堡選單。
黃金法則:
數值縮放(size / spacing)用clamp(),結構與行為改變用@media。
6. 常見錯誤&避雷指南
錯誤 1:什麼都想用 clamp() 取代
- 佈局崩壞、漢堡選單壞掉,大多是想拿
clamp()取代 layout media queries。 - 解法:只把「單純大小」相關的地方換成
clamp(),layout 照用@media。
錯誤 2:vw 值太大,縮放過頭
/* Bad:在小螢幕直接頂到 max,clamp 形同虛設 */
font-size: clamp(16px, 10vw, 32px);
- 400px 螢幕 →
10vw = 40px,直接被上限 32px 卡住。 - 建議:多數情境
1vw ~ 5vw比較合理。
錯誤 3:最小值設太小,導致難以閱讀
/* Bad:8px 幾乎看不到 */
font-size: clamp(8px, 2vw, 24px);
- 文字最小值不要低於 14px,主體內容建議 16px 起跳。
錯誤 4:只在 DevTools 看,沒在實機測
- clamp 在模擬器上看起來 ok,但實機上可能顯得太大/太小。
- 解法:至少用一台實機或遠端測試服務(BrowserStack 等)過一輪。
7. 實務工作流:怎麼在專案裡導入 clamp()
-
先做好桌機版(固定 px 值)
-
找出「應該隨螢幕縮放」的東西
- 各層級標題、段落文字
- 卡片、Section 的內外距
- 容器最大寬度、Grid 間距、圓角等
-
把固定值改成
clamp()/* Before */
h1 {
font-size: 48px;
}
.section {
padding: 40px;
}
/* After */
h1 {
font-size: clamp(32px, 4vw, 48px);
}
.section {
padding: clamp(20px, 3vw, 40px);
} -
在幾個關鍵寬度檢查
- 375px、768px、1024px、1440px
-
微調
vw(必要時加上+ px偏移) -
保留「只負責佈局/顯示切換」的媒體查詢
實務上通常可以減少 60–70% 以上、原本只用來「改大小」的媒體查詢。
8. 瀏覽器支援與 fallback 策略
clamp() 的支援度目前已超過 96%(Chrome / Firefox / Safari / Edge 都支援),剩下主要是非常老舊的瀏覽器。
若想保險一點,可以這樣寫 fallback:
.heading {
font-size: 32px; /* 舊瀏覽器 fallback */
font-size: clamp(24px, 4vw, 48px); /* 支援 clamp 的覆蓋上來 */
}
不認得 clamp() 的瀏覽器會忽略第二行,只用 32px。
9. Quick Reference:常用 clamp() 模板
/* 標題字體 */
h1 {
font-size: clamp(32px, 5vw, 64px);
}
h2 {
font-size: clamp(24px, 4vw, 48px);
}
h3 {
font-size: clamp(20px, 3vw, 32px);
}
/* 內文字體 */
p {
font-size: clamp(16px, 1.5vw, 20px);
}
/* 容器間距 */
.container {
padding: clamp(16px, 4vw, 80px);
margin: clamp(20px, 5vw, 100px) auto;
}
/* 內容寬度 */
.content {
max-width: clamp(320px, 90vw, 1200px);
}
10. 整體觀念總結(一句話記住)
- 用
clamp()處理「要隨螢幕平滑變化的數值」:字體大小、間距、寬度、圓角等。 - 用
@media處理「版面與行為改變」:欄位數變化、導覽列型態、顯示/隱藏元素。 - 實作策略:先寫出桌機版固定值 → 把該流動的數值改成
clamp()→ 只保留少量關鍵媒體查詢。
記憶點:
「clamp() 管 size,media query 管 layout」── 這樣用,你的 CSS 會更短、更好維護,也更接近真正的 Fluid Design。