textarea 高度自适应必须用 js + scrollheight 实现,核心是先设 height: auto 再读 scrollheight,并需处理 ios 输入法、visualviewport 变化、box-sizing、字体继承及 resize 等兼容细节。

field-sizing 不是可用的 CSS 属性
直接写 field-sizing: content 对 textarea 无效——它不是标准属性,Chrome 123+ 仅对 input[type="number"] 等极少数控件实验性支持,textarea 完全不在此列。Firefox 和 Safari 完全无视该声明,写了等于白写。你看到的“生效”效果,基本来自误判:比如把 height: auto + scrollHeight JS 逻辑、或 resize: none + width: fit-content 当成了 field-sizing 的作用。
textarea 高度自适应必须用 JS + scrollHeight
这是当前唯一跨浏览器、可上线的方案。核心逻辑简单,但漏掉任一细节都会导致高度错乱或 iOS 上跳动:
-
min-height和max-height必须用 CSS 显式设置,否则空内容时塌成一条线,长内容时撑爆页面 - JS 中必须先设
el.style.height = 'auto',再读el.scrollHeight;不重置 height,scrollHeight 会卡在旧值 -
box-sizing: border-box必须显式声明,否则scrollHeight包含 padding/border,赋值后高度重复叠加 - 父容器不能有
overflow: hidden,否则截断内容,scrollHeight返回错误值
iOS Safari 的三个关键兼容点
移动端最容易出问题的地方不在逻辑本身,而在时机和状态判断:
- 只监听
input事件不够:iOS 拼音输入法未上屏时就触发了input,但scrollHeight还没更新;需配合compositionstart/compositionend标记输入状态 - 不加
requestAnimationFrame直接赋值,会导致高度计算滞后一帧,出现“文字已换行、框还没长高”的跳动 - 键盘弹起时
visualViewport变化会让scrollHeight瞬间失准;必须监听resize事件并触发一次重算
别忽略 textarea 的默认盒模型偏差
即使 JS 逻辑正确,视觉错位仍常源于基础样式没对齐:
-
textarea默认box-sizing: content-box,而项目里其他表单控件大概率是border-box,导致宽度计算不一致;必须显式写textarea { box-sizing: border-box; } - 字体继承不可靠:Chrome/Firefox/Safari 对
font-family、font-size、line-height的回退行为不同,必须三者同时声明,且推荐用 px 单位 -
resize: both(右下角拖拽手柄)会干扰最小尺寸计算,应统一禁用:resize: none
compositionstart/compositionend 的兜底处理——中文用户在 iOS 上频繁遇到高度跳动,几乎都源于此。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











