写了八年 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,仅用于设计明确要求的装饰性标题。
三步下一步
- 搜:翻项目里有没有 FitText.js / fitty / TextFill / FlowType 的引用——现在可以扔掉了
- 找:页面上哪些地方在用 viewport magic number 或 JS 做文字适配——换成 text-fit: grow/shrink
- 试:在 Chrome 150 里跑一个 Demo,感受一下 consistent 和 per-line 的视觉差异
/* 从现在起,标题自适应宽度只需要这一行 */
h1 { text-fit: grow; }
评论区
登录后可评论。