如何实现textarea内容溢出时向上扩展高度(聊天输入框场景)
让聊天输入框(textarea)向上扩展高度
要实现textarea向上扩展,核心是通过CSS布局让输入框固定在底部,内容增加时向上撑开容器,同时调整JS的高度计算逻辑避免异常。
解决方案步骤:
- 给textarea的父容器设置flex布局+垂直底部对齐,确保输入框始终贴在容器底部,内容增多时向上扩展
- 修正textarea的样式,避免默认布局属性干扰高度计算
- 优化JS逻辑,解决退格时scrollHeight异常的问题
修改后的完整代码:
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>聊天输入框向上扩展</title> <link href="style.css" rel="stylesheet" type="text/css"> <script type="module" src="script.js" defer></script> </head> <body> <header> <h1>聊天输入框示例</h1> </header> <main> <!-- 用div替代p作为父容器,更方便控制布局 --> <div class="input-container"> <textarea class="chat-input" id="article"></textarea> </div> </main> </body> </html>
CSS
/* style.css */ main, header { max-width: 600px; margin: auto; } /* 核心:父容器设置flex,垂直方向底部对齐 */ .input-container { display: flex; align-items: flex-end; min-height: 2em; /* 设置最小高度,对应输入框默认高度 */ width: 80%; margin: auto; } .chat-input { font-family: 'Times New Roman', Times, serif; font-size: 1em; border: 1px solid #EEE; outline: none; padding: 0.1em; margin: 0; resize: none; width: 100%; border-radius: 0.2em; /* 去掉默认的垂直对齐,避免布局偏移 */ vertical-align: bottom; } .chat-input:focus { border: 1px solid #DDD; }
JavaScript
document.querySelectorAll('.chat-input').forEach(element => { // 初始化高度,用scrollHeight减去padding,避免高度溢出 const computedStyle = window.getComputedStyle(element); const paddingTop = parseInt(computedStyle.paddingTop); const paddingBottom = parseInt(computedStyle.paddingBottom); element.style.height = `${element.scrollHeight - paddingTop - paddingBottom}px`; element.addEventListener('input', event => { const target = event.target; // 先重置高度为auto,再重新计算scrollHeight target.style.height = 'auto'; // 减去padding值,确保高度计算准确,解决退格时scrollHeight异常问题 target.style.height = `${target.scrollHeight - paddingTop - paddingBottom}px`; }); });
关键说明:
- 父容器用
align-items: flex-end让textarea始终贴在底部,当textarea高度增加时,会向上撑开父容器,视觉上就是输入框向上扩展 - JS中计算高度时减去上下padding,避免默认padding导致scrollHeight计算偏差,解决退格时高度异常的问题
- 把原来的
<p>父容器换成<div>,因为<p>有默认的margin和line-height,会干扰flex布局的垂直对齐
内容的提问来源于stack exchange,提问作者electronixG
相关产品推荐
相关产品推荐

