响应式布局里最让人头疼的就是字体大小:手机上要小,桌面要适中,大屏要大气。过去靠一堆 @media 断点,现在有了 clamp(),一行 CSS 搞定"最小值-理想值-最大值"的三段式响应。

clamp() 是什么

clamp() 是 CSS 数学函数,接收三个参数:

css syntax
属性: clamp(最小值, 理想值, 最大值);

浏览器会这样算:

  • 如果理想值 小于 最小值 → 用最小值
  • 如果理想值 大于 最大值 → 用最大值
  • 否则 → 用理想值

一句话:在最小和最大之间,跟着理想值走。

响应式字体的标准答案

css responsive-font.css
body {
  font-size: clamp(16px, 2vw + 8px, 20px);
}

解读一下:

  • 16px:手机上的最小字号,保证可读
  • 2vw + 8px:理想值,随视口宽度线性增长
  • 20px:大屏上的最大字号,避免字太大

效果:手机上 16px,随屏幕变宽慢慢长大,到 1200px 宽时达到 20px 封顶。中间没有任何断点。

💡 小技巧:用 rem 更灵活:clamp(1rem, 0.5rem + 1.5vw, 1.25rem),还能继承用户的浏览器字号设置。

不止字体:clamp() 的万能用法

任何能写长度值的地方都能用 clamp():

css more-uses.css
/* 响应式容器宽度 */
.container {
  width: clamp(300px, 80vw, 1200px);
}

/* 响应式间距 */
.section {
  padding: clamp(1rem, 5vw, 4rem);
}

/* 响应式圆角 */
.card {
  border-radius: clamp(4px, 1vw, 16px);
}

/* 响应式行高 */
h1 {
  line-height: clamp(1.2, 1.1 + 0.5vw, 1.6);
}

和传统 media query 的对比

对比项@media 断点clamp()
代码量多组断点,代码膨胀一行搞定
过渡断点间突变平滑连续
可维护性改断点值要算改三个参数即可
可读性分散在多处一眼看懂范围
浏览器支持所有浏览器Chrome 79+, Firefox 75+, Safari 13.1+

两个坑要注意

坑一:vw 在移动端会跳

手机上地址栏收起/展开时,视口宽度变化,vw 跟着跳,字号也跟着跳。如果不想让字号抖动,用 dvw(动态视口宽度)代替:

css mobile-fix.css
body {
  font-size: clamp(16px, 2dvw + 8px, 20px);
}

坑二:clamp() 不能嵌套

clamp() 里不能再写 min() / max() / clamp(),会解析失败。需要嵌套时,用 calc() 算出理想值再传进去。

⚠️
注意参数顺序
clamp(最小, 理想, 最大) 不能写反。如果最小 > 最大,浏览器会直接忽略整行。调试时先看 DevTools 有没有被划掉。

总结

clamp() 是响应式设计的瑞士军刀。记住三个参数:最小保底、理想跟随、最大封顶,从此告别 @media 的断点地狱。

好的响应式设计,用户感觉不到"断点"的存在——他们只会觉得"刚刚好"。