Textarea需用JavaScript监听input事件并设style.height为scrollHeight来实现自适应高度,初始需调用一次调整函数,应设置min-height和max-height防异常拉伸,contenteditable虽自适应但不参与表单提交故不推荐。
Bootstrap本身不提供原生的自适应高度textarea,它默认是固定行数(rows)的静态控件。直接设height: auto无效,因为textarea不会像div那样根据内容重排;必须靠JavaScript监听输入并动态调整scrollHeight。
scrollHeight实时同步高度(推荐方案)核心逻辑:每次input事件触发后,把textarea.style.height设为scrollHeight,再加一点内边距缓冲。注意不能直接用clientHeight或offsetHeight,它们不含溢出内容高度。
实操建议:
input和keydown(尤其回车),但避免重复触发,可用requestAnimationFrame节流min-height和max-height,防止过矮或无限拉伸(例如max-height: 200px).form-control已含box-sizing: border-box,所以直接赋scrollHeight即可,无需手动减去padding/borderconst $ta = document.querySelector('textarea');const adjustHeight = () => { $ta.style.height = 'auto'; $ta.style.height = $ta.scrollHeight + 'px';};$ta.addEventListener('input', adjustHeight);adjustHeight(); // 初始化
contenteditable替代textarea?虽然div[contenteditable]天生自适应,但它不是表单控件:form.submit()不收集其值,FormData不包含它,且需手动处理换行符(n vs <br>)、焦点管理、ARIA属性等。在需要真实表单提交的场景下,这是得不偿失的绕路。
常见错误现象:
keyup,漏掉粘贴(paste)、剪切(cut)、拖入文本等操作max-height,导致长文本把整个页面顶开.col或.card-body里使用时,忘记给父容器设overflow: visible(默认可能裁剪)如果想加平滑缩放过渡,不能直接对height加transition(因height: auto无法过渡),得用max-height模拟:
textarea { max-height: 100px; transition: max-height 0.2s ease-out;}textarea.expanded { max-height: 300px;}
此时JS只需切换.expanded类,由CSS控制上限。但要注意:这个方案有硬编码高度,不如scrollHeight精准;且当内容高度介于100–300px之间时,动画可能不自然。
真正容易被忽略的是:移动端软键盘弹起时,scrollHeight可能短暂失真(尤其iOS Safari),建议加个setTimeout微调延迟或监听resize事件兜底。