跳到主要内容

用 clamp() 做流式字号:告别一堆媒体查询的响应式排版做法

从最小最大字号和视口范围算出一条 clamp(),字号随视口缩放又有上下限。一篇讲清 clamp 三参数怎么填、流式字号怎么落到真实 CSS,以及怎么少写几十行断点。

发布于 作者 李雷
#CSS #流式字号 #clamp #响应式排版 #前端

用 clamp() 做流式字号:让标题随视口缩放又有上下限

过去做响应式字号,我习惯给每一档标题写一串媒体查询:手机一个 font-size,平板一个,桌面再一个。h1 到 h6 加上正文,一套下来三四十行 @media,过几个月谁都不敢动。clamp() 出来之后,这套写法基本可以退休了。一行声明,字号在两个视口之间平滑插值,小屏不会太小,大屏不会失控。

下面把 clamp 做流式字号这件事讲透:三个参数各自管什么、一段真实的 font-size 长什么样、以及为什么它能替掉那一摞断点。

clamp() 的三个参数,各管一件事

clamp(min, preferred, max) 收三个值,逻辑很直白:

  • min:字号的下限。视口再窄,字号也不会小于它。
  • preferred:首选值,通常是一段带 vw 的表达式。视口变宽,它跟着变大,这是"流式"的来源。
  • max:字号的上限。视口再宽,字号也不会大于它。

浏览器在这三者里取中间那个:preferred 小于 min 时用 min,大于 max 时用 max,落在区间内就用 preferred 本身。这正是流式字号想要的行为,随视口缩放,但两端各有一道闸。

光有 vw 不够,纯 font-size: 4vw 在 360px 手机上是 14.4px,在 1920px 屏上是 76.8px,小屏太小大屏太大,没有任何兜底。clamp 的价值就在于给这条线封了顶也兜了底。

一段真实的 clamp 字号长什么样

说再多不如看一条。假设正文要在 360px 视口是 16px、在 1440px 视口是 20px,算出来的声明是这样:

body {
  font-size: clamp(1rem, 0.875rem + 0.556vw, 1.25rem);
}

拆开看:1rem 是下限(16px),1.25rem 是上限(20px),中间 0.875rem + 0.556vw 是那条斜线,截距 0.875rem、斜率 0.556vw。把视口代进去验算:360px 时 0.875 × 16 + 0.556 × 3.6 ≈ 16px,1440px 时 0.875 × 16 + 0.556 × 14.4 ≈ 20px,两端精确命中。中间任意宽度都是线性过渡,不会跳变。

这个 rem + vw 的组合不是随便凑的,它来自 Mike Riethmuller 2016 年那套模数流式字号公式:vw 给斜率、rem 给截距,clamp 在两端封口。手算容易把 rem 和 px 搞混导致截距错位,所以我一般直接用 CSS clamp() 流式字号生成器 把整套 h1 到 small 一次算出来,每行都是可粘的声明。

一条声明替掉一摞媒体查询

传统写法里,一档标题往往要这样堆:

h1 { font-size: 28px; }
@media (min-width: 768px) { h1 { font-size: 40px; } }
@media (min-width: 1200px) { h1 { font-size: 56px; } }

三个断点之间是台阶式跳变,768px 那一刻字号"咔"地一跳,过渡很硬。换成 clamp 之后,这三行变一行,而且 768px 不再是断点,字号从 360 到 1440 一路平滑长上去。h1 到 h6 加正文一共八档,原本可能是二十多行媒体查询,现在是八行 font-size: clamp(...)

要分清的一点:clamp 里的视口范围管的是"字号在哪个区间插值",不是"布局在哪里换列"。小于最小视口字号停在 min,大于最大视口停在 max,而 grid 改几列、侧栏收不收,这些布局重排还是得靠单独的 @media。流式字号替掉的是字号的断点,不是所有断点。

两端用不同的比例,小屏克制大屏放开

做整套字号表时,我会给小屏和大屏各挑一个模数比例。同一个比例往往小屏合适、大屏就崩:360px 手机上给 h1 套黄金比例(1.618),一行标题占满整屏,喧宾夺主;1920px 桌面上套小二度(1.067),h1 和正文几乎一样大,层级又分不出来。

所以常见做法是小屏用大三度(1.25)、大屏用纯四度(1.333),把"小屏要收着、大屏可以放"的设计直觉编进比例里。两端选一样就退化成单一比例,数学上也成立,只是没用上这个特性。

别踩的两个坑

第一个:最小档字号别设太小。正文设 14px 听着合理,但 small 比正文还小一档,1.333 的比例下手机上就是 10.5px,Lighthouse 会标小字号,用户也看不清。上线前先看一眼 small 那行在最小视口的 px 值。

第二个:输出尽量用 rem 而不是 px。rem 相对根字号,用户为无障碍把浏览器默认字号从 16 调到 20,你的排版会跟着放大;px 是绝对值,用户调了你纹丝不动,这是无障碍倒退。换算也不难,就是 值 ÷ 16。如果你还在纠结 px 和 rem 之间怎么倒,px 转 rem 换算器 能帮你把一摞像素值批量换成 rem。

小结

clamp() 把响应式字号从"堆断点"变成了"定上下限再连一条线"。理解了三个参数、知道 rem + vw 那条斜线怎么命中两端,流式排版就不再是玄学。剩下的算术交给工具,你专心调比例和视觉就行。


Made by Toolora · Updated 2026-06-13