响应式字号别再堆媒体查询:clamp() 与 Type Scale 一套搞定

一套能落地的流式排版方案:clamp(最小, 首选, 最大) 的几何意义、rem+vw 混合公式怎么推导、从 xs 到 4xl 的完整字号阶梯、为什么不能用裸 vw,以及 CSS 变量 / Tailwind / SCSS 三种落地写法。

约 7 分钟读完 · 更新于 2026-10-21 · 文中每条都能在下面的配套工具里动手验证

clamp() 的几何意义:三点定一条线

clamp(min, preferred, max) 的行为:视口很小时取 min,很大时取 max,中间沿 preferred 线性变化。想让字号在 360px 视口是 16px、在 1200px 视口是 22px,preferred 就必须是一条过这两点的直线——这就是所有公式生成器的原理。

过两点的直线:斜率 + 截距
目标:360px → 16px,1200px → 22px
斜率 slope = (22-16)/(1200-360) = 0.00714 px 视口
化为 vw:0.00714 × 100 / 100 → 0.714vw
截距 b = 16 - 0.714 × 3.6 = 13.43px → 0.84rem

h2 { font-size: clamp(1rem, 0.84rem + 0.714vw, 1.375rem); }
为什么 preferred 里必须有 rem
h1 { font-size: clamp(1rem, 2.5vw, 2rem); }   /* 可用但有缺陷 */
h1 { font-size: clamp(1rem, 0.9rem + 1.5vw, 2rem); } /* 推荐 */

/* 纯 vw 的 preferred 意味着:用户把浏览器默认字号
   从 16 调到 24,这段文字毫无反应——无障碍硬伤。
   rem 部分保证用户设置始终生效。 */

一套完整的字号阶梯

单条 clamp 很容易,工程化的问题是「标题和正文的比例在不同视口是否协调」。做法是固定两端各一套比例(如小屏 1.2 倍、大屏 1.25 倍的 minor third),每级都过一条自己的直线。生成的阶梯一次性贴进全局样式,之后再也不写字号媒体查询。

级别小屏 (360px)大屏 (1200px)典型用途
xs12px13px标签、注释、时间戳
sm14px15px辅助说明、表单提示
base16px17px正文
lg19px21px小标题、导语
xl23px27px区块标题
2xl28px33px页面标题
4xl40px56pxHero 大标题

落地清单

  1. 先定基准:正文小屏 16px 起、行高 1.5+,这是无障碍底线
  2. 选两端比例(常见 1.2 / 1.25),确定 360px 与 1200px 两个端点——别用 0 到无穷大,区间越宽中段越不可控
  3. 用工具生成每级的 clamp(),输出 CSS 变量或 Tailwind fontSize 配置
  4. 全部字号走变量:font-size: var(--fs-lg);审查时全局搜字面值 px 字号应为零
  5. 缩放窗口实测两端点与中段,确认行高与截断没有破版

常见问题

clamp() 兼容性怎么样?

2020 年年中起所有主流浏览器稳定支持(Chrome 79 / Safari 13.1 / Firefox 75)。不支持的老浏览器会整条声明作废——把 clamp 写在带 fallback 的第二行即可:先写固定 font-size,再写 clamp 覆盖。

视口区间为什么常用 360–1200px?

360 是当前最小的主流手机 CSS 宽度,1200 之后布局通常已定宽(max-width 容器),视口再宽字号也不该跟着涨。区间外的钳制正是 min/max 的职责。

这套方法也适用于间距吗?

适用,而且效果更好:区块间距从 24px 流式涨到 64px 很常见。用 clamp-generator 直接算,或用 type-scale 生成一套间距变量,与字号阶梯同构维护。

📂

松开以自动格式化

支持 .json / .sql / .csv / .html / .css / .xml / .yaml 文件