移动端表格内textarea失效的根源是table-cell压缩内容且不响应自适应高度,导致键盘顶飞、文字溢出、高度卡死、光标不可见;需用绝对定位包裹层+scrollHeight动态设高+focus/blur手动滚动修复。

移动端表格里嵌 textarea,不加处理基本就是“输入框被键盘顶飞、文字横向溢出、高度卡死、光标看不见”四连击。核心问题不是表格本身,而是 textarea 在受限容器中失去了对自身尺寸和滚动行为的控制权。
为什么表格里的 textarea 在手机上会失效
表格单元格(td)默认是 display: table-cell,它会压缩内容、忽略 height: auto,且不响应 min-height;而 textarea 的自适应逻辑依赖于 scrollHeight 和可伸缩的父容器。两者叠加,JS 设置的 height 会被 td 截断或重置。
-
td的vertical-align: middle(默认)会让textarea垂直居中,但 JS 动态改高后,视觉位置可能偏移甚至被裁剪 - 移动端虚拟键盘弹出时,
window.innerHeight缩小,但td不会自动重排,导致textarea被挤出可视区 - 未设置
wrap="soft"时,长无空格文本(如 base64 片段)会强制横向溢出,撑开整个表格,触发页面横向滚动
textarea 自适应高度 + 表格兼容写法
不能只靠 JS 改 height,得让 td 主动“让位”。关键是在 td 上加一层包裹,并用 CSS 触发弹性行为。
- 给
td加position: relative,内部用div包裹textarea并设position: absolute; top: 0; left: 0; right: 0; bottom: 0; -
textarea设width: 100%; height: 100%; box-sizing: border-box;,并显式声明wrap="soft" - JS 中监听
input事件,每次更新前先设textarea.style.height = 'auto',再赋值textarea.scrollHeight + 'px',避免累积误差 - 为防 iOS 键盘收起后高度残留,建议在
blur时重置一次:textarea.style.height = textarea.rows + 'em'
移动端键盘遮挡与聚焦修复
iOS 和部分安卓 WebView 对 textarea 聚焦后的滚动定位极不可靠,尤其在 table 内部。不能依赖 scrollIntoView,得手动干预。
立即学习“前端免费学习笔记(深入)”;
- 在
focus事件中,用setTimeout延迟 100ms 再调用textarea.scrollIntoView({ block: 'nearest' }),避开键盘动画帧 - 对 iOS,额外加判断:
if (/iPad|iPhone|iPod/.test(navigator.userAgent)),然后用textarea.parentElement.parentElement.scrollBy(0, -100)往上微调 - 禁用
td的overflow: hidden(如有),否则scrollIntoView会被截断
真正难的不是让 textarea 变高,而是让它在 table 的 rigid layout 里“呼吸”——既要撑开,又不能撑破;既要响应输入,又不能被键盘劫持。很多项目最后放弃表格布局,不是因为不会写 JS,而是 table-cell 的渲染机制和移动端视口变化根本不在一个节奏上。



















