配了八年表单,今天才发现 textarea 高度从来不归 CSS 管——field-sizing 把这件事彻底原生化了

做过表单的人大概都踩过这个坑——评论框、备注、发帖框,每次想让输入框跟着内容自动撑高,都得写一段绕来绕去的 JavaScript:监听 input、重置高度为 auto、立刻读 scrollHeight、再写回去。框架不一样但本质一样,每个项目里都躺着一份这个逻辑。

2026 年,这件事变成了纯 CSS 的事。

一行 CSS,替代一个 JS 工具函数

field-sizing 是 CSS 新增的属性,核心就两个值:

/* 固定尺寸,传统行为 */
textarea { field-sizing: fixed; }

/* 内容驱动尺寸,浏览器自己算 */
textarea { field-sizing: content; }
}

加一行 field-sizing: content,textarea 就能跟着输入的内容自动长高,不再需要任何 JS。删文字,它自动缩回去。

同样的属性对 <input><select> 也生效:

  • input:宽度沿 inline 轴增长,适合标签输入、用户名、搜索框这类需要「刚刚好够用」的场景
  • select:宽度跟随当前选中项,不再为最长选项预留死宽度
  • textarea:高度随内容增长,最常用的场景

为什么等了这么久

这个能力在 2026 年之前一直是 Chrome 独占。Safari 到 2025 年 12 月(版本 26.2)才跟进,Firefox 最晚,2026 年 6 月 Firefox 152 发布后,三大浏览器引擎才算凑齐。正是这个时间节点让 field-sizing 正式成为 Baseline 2026——意味着 Blink、WebKit、Gecko 全部在最新版里支持了。

从 caniuse 数据看,Chrome 123+、Safari 26.2+、Firefox 152+,全球覆盖率 93%+。现在上线不用 flag、不用 polyfill。

别让它无限长下去

光写 field-sizing: content 不够,它没有内置上限。用户粘贴进去一大段文字,textarea 会一直长到把整个页面顶走。MDN 官方文档和 Chrome 文档都明确建议:配合 min/max 约束一起用。

textarea {
  field-sizing: content;
  min-height: 3lh;    /* 空的时候至少三行,别塌成一条线 */
  max-height: 12lh;   /* 长文章到 12 行就打住,内部滚动 */
  overflow-y: auto;   /* 超长后内部滚动,不撑页面 */
}

这里用 lh(line-height 单位)而不是 px,让上限跟随字体大小走,比例永远对。

input 同理:

input[type="text"] {
  field-sizing: content;
  min-width: 8ch;     /* 空的时候别缩成仅光标宽 */
  max-width: 100%;    /* 不超过父容器 */
}

渐进增强写法

field-sizing 还没跨过「广泛可用」门槛(Baseline 广泛可用预计 2028 年 12 月),如果你的用户里有不少还在用旧版浏览器,需要写渐进增强:

/* 先写传统固定尺寸,旧浏览器直接用这套 */
textarea {
  min-height: 80px;
  max-height: 400px;
}

/* 支持的浏览器叠加新行为 */
@supports (field-sizing: content) {
  textarea {
    min-height: 3lh;
    max-height: 12lh;
    field-sizing: content;
  }
}

旧浏览器忽略不认识的属性,这套渐进增强是标准做法,不会破坏无障碍可用性。

三个容易踩的坑

坑一:同时写了固定宽高

/* 这种写法 field-sizing: content 等于无效 */
textarea {
  height: 150px;        /* 把高度锁死了 */
  width: 100%;
  field-sizing: content;
}

去掉 height 或改用 min-height,属性才生效。

坑二:placeholder 被算进内容宽度

input 的 placeholder 文本也会触发宽度计算,长 placeholder 会让 input 一上来就很宽。设计时注意 placeholder 长度。

坑三:Safari 对 select 的行为略有不同

Safari 下 select 宽度跟随的是当前选中项文字,不是最长选项。看起来更合理,但跨浏览器测试时注意视觉一致性。

下一步

打开你的表单组件,搜一下有没有 auto-resize / scrollHeight 相关的 JS 代码。如果有,这周就能删掉,换成三行 CSS:

textarea {
  field-sizing: content;
  min-height: 3lh;
  max-height: 12lh;
}

先把评论框改了,这是最明显能感受到价值的地方。

评论区

0 条评论

登录后可评论。