写了八年 CSS,每次想给标题文字自动缩放都要靠一个库——今天这件事被 text-fit 一行彻底原生化了

每次做响应式页面,标题文字要自动撑满容器宽度,全靠工程师手写一堆 hack:FitText.js、viewport 单位、SVG viewBox……反正没有一个是干净的。Chrome 150 说,不用了,一行 CSS 给你原生搞定。

之前的解法,没有一个省心

做标题文字自适应宽度的历史,就是一部前端黑魔法百科全书。

FitText.js 是老牌方案,用 JS 把 font-size 动态缩放到容器宽度。但它依赖 width 固定、要调一个 magic number、每次 resize 要重新算,对性能敏感的页面来说等于多跑了一帧布局。

viewport 单位 思路是 font-size: 3vw 这样——找到一个数字让文字刚好撑满容器。但这个数字是「试出来的」,换一个字体、换一种语言(德语单词普遍比英语长)就失效,每次改设计都要重新调。

SVG viewBox 是更 hack 的方案:把文字放进 SVG,用 viewBox 比例换算字号。同样的问题,每次改容器都要重算 viewBox,维护成本极高。

这三种方案共同的问题是:没有一种是浏览器「认识」的——都是靠数学 hack 绕过去,浏览器并不知道你在「让文字适配容器」。

text-fit:浏览器原生认识这件事了

Chrome 150(2026年6月)引入的 text-fit 属性,终于让浏览器知道「把文字缩放到容器宽度」这件事了。

.title {
  font-family: system-ui;
  text-fit: grow;
}

这行 CSS 告诉浏览器:把这个元素的文字字号,缩放到刚好填满容器宽度。浏览器自己在布局阶段就把数学做完了,不会有额外的 reflow。

text-fit 有两大家族的值:

第一家族:grow/shrink——单向缩放

  • grow:文字比容器窄时,放大到撑满;比容器宽时不处理
  • shrink:文字比容器宽时,缩小到刚好;比容器窄时不处理

第二家族:consistent/per-line——多行行为控制

多行文字时,consistent 以最宽那行为基准缩放所有行,per-line 则是每行独立缩放到自己的容器宽度(每行宽度可以不同)。

可选参数控制缩放上下限:

/* 最多缩放到 48px,最小不低于 12px */
.title {
  text-fit: grow 12px 48px;
}

/* shrink 模式下,超出容器则缩小,最多缩到 12px */
.subtitle {
  text-fit: shrink 12px;
}

值得注意的是,text-fit 只影响渲染结果,getComputedStyle() 返回的 font-size 值不变。这意味着它不会干扰依赖字号做其他计算的场景。

三行代码落地

基础用法:响应式标题

.card-title {
  text-fit: grow;
  /* 配合 @supports 做渐进增强 */
}

@supports (text-fit: grow) {
  .card-title {
    font-size: 1rem; /* 降级兜底,实际不生效 */
  }
}

shrink 模式:防止长文本溢出

用户输入的内容、多语言站点的翻译文本,往往长度不可控:

.badge {
  text-fit: shrink;
  max-width: 100%;
  white-space: nowrap;
}

三个坑

1. Safari 和 Firefox 还没支持

截至 2026年9月,text-fit 只有 Chrome 150+ 和 Edge 150+ 支持,全球覆盖率约 59%。Safari 和 Firefox 均未实现,必须加 @supports 渐进增强,不能直接上线当唯一方案:

@supports (text-fit: grow) {
  .title { text-fit: grow; }
}

2. 多行场景的 per-line 语义要注意

per-line 模式每行独立缩放,适合每行宽度固定的场景(如列表项标题)。但如果行宽度本身不均匀(文本对齐导致),per-line 可能产生视觉上不一致的字号差距。consistent 模式更安全,以最宽行为基准统一缩放。

3. 无障碍:用户放大网页字体时不应继续缩放

CSSWG 规范仍在讨论 text-fit 对用户字体偏好(Ctrl+/Ctrl-)的影响。目前建议:不要在用户可放大字体的正文区域使用 text-fit,仅用于设计明确要求的装饰性标题。

三步下一步

  1. :翻项目里有没有 FitText.js / fitty / TextFill / FlowType 的引用——现在可以扔掉了
  2. :页面上哪些地方在用 viewport magic number 或 JS 做文字适配——换成 text-fit: grow/shrink
  3. :在 Chrome 150 里跑一个 Demo,感受一下 consistent 和 per-line 的视觉差异
/* 从现在起,标题自适应宽度只需要这一行 */
h1 { text-fit: grow; }

评论区

0 条评论

登录后可评论。

阿柯·前端架构 16 阅读