必须先设 textarea.style.height = 'auto' 再赋值 scrollheight,否则 ios/ie11 下高度计算错误;需配合 min-height/max-height css、box-sizing: border-box 及换行符归一化等兼容处理。

直接用 scrollHeight 动态设 style.height 是可行的,但必须先清空旧高度再读值,否则 iOS、IE11 和快速输入时都会出错。
为什么 textarea.style.height = textarea.scrollHeight + 'px' 会越撑越高
常见错误是跳过重置步骤。一旦之前设过固定 height(比如上一次输入留下的 200px),浏览器就会把它当约束条件,导致 scrollHeight 计算偏小——尤其在 iOS Safari 和 IE11 上更明显。
- 每次触发前必须加
textarea.style.height = 'auto',让元素回归自然流式计算逻辑 - 不加这句,删文字时高度卡住不缩、粘贴大段后底部留白、回车换行光标跳动都是典型表现
-
offsetHeight和clientHeight永远不准,它们不含溢出区域,不能替代scrollHeight
移动端和 IE11 的兼容性坑点
iOS Safari 对 scrollHeight 更新有微小延迟;IE11 把 \r\n 当一个字符算,而现代浏览器统一按 \n 处理,导致空行末尾的 scrollHeight 偏小 1 行。
- iOS:必须用
requestAnimationFrame包一层,比setTimeout(, 0)更稳,尤其在 120Hz 屏上 - IE11:可做换行符归一化 ——
textarea.value = textarea.value.replace(/\r\n/g, '\n') - 若必须保留
\r\n(如日志类场景),就对 IE11 单独补偿:const height = textarea.scrollHeight + (isIE11 ? 2 : 0)
min-height 和 max-height 必须用 CSS 控制
光靠 JS 算高度不行,这两项必须走 CSS,否则空 textarea 会塌成一条线,或者用户狂输时无限制拉伸。
- CSS 必须设
min-height(如80px),保证初始有可点击区域 -
max-height控制上限(如300px),超出后才出现滚动条 - 必须显式写
overflow-y: auto,否则超限时内容被裁切 - 别用
height: 100%或flex: 1直接套在textarea上——它会和 JS 高度冲突
样式一致性常被忽略
scrollHeight 的值依赖真实渲染高度,所有影响高度的样式(padding、border、line-height、字体)必须和 JS 计算时完全一致,否则结果偏差肉眼可见。
- Chrome 开发者工具里关掉“user agent stylesheet”再看 computed 值,才能确认真实渲染高度
-
box-sizing: border-box很重要,确保padding和border不额外增加高度 - 顺手加上
resize: none; overflow: hidden;,避免用户拖拽破坏自适应逻辑
最易被忽略的是:没设 min-height 和 max-height,以及样式与 JS 计算脱节。这两点不出问题时一切正常,一出就是光标跳、高度卡、iOS 粘贴后留白——而且很难复现和定位。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











