textarea的scrollHeight单行内容时仍为两行高度,如何实现单行适配?
解决textarea单行内容时scrollHeight计算为两行高度的问题
这个坑我之前踩过好几次!其实问题根源主要来自两个地方:浏览器给<textarea>的默认样式和**scrollHeight的计算逻辑**。
为什么会出现这个问题?
浏览器默认会给<textarea>设置rows="2"属性,同时自带上下内边距(不同浏览器略有差异)。哪怕你只输入一行文字,scrollHeight会把默认的两行高度基础加上内边距都算进去,导致看起来像是两行的高度。
解决方案:三步搞定
1. 先重置textarea的基础属性
把rows设为1,去掉默认的两行高度起点:
<textarea rows="1" placeholder="输入内容..."></textarea>
2. 统一textarea的样式,避免浏览器差异
给textarea设置明确的内边距、行高,隐藏滚动条和默认拖拽:
textarea { padding: 8px 12px; /* 自定义上下内边距,按需调整 */ line-height: 1.5; border: 1px solid #e0e0e0; resize: none; /* 去掉默认的拖拽调整按钮 */ overflow: hidden; /* 隐藏滚动条,因为我们要自动伸缩 */ font-size: 14px; /* 统一字体大小,避免行高计算偏差 */ }
3. 优化JS的高度计算逻辑
核心是每次计算前先把高度重置为auto(避免之前的高度影响计算),然后用scrollHeight减去上下内边距的总和,得到真正的内容高度:
const autoResizeTextarea = document.querySelector('textarea'); function adjustTextareaHeight() { // 先重置高度为auto,确保scrollHeight能准确计算当前内容高度 autoResizeTextarea.style.height = 'auto'; // 获取上下内边距的数值 const computedStyle = getComputedStyle(autoResizeTextarea); const paddingTop = parseInt(computedStyle.paddingTop); const paddingBottom = parseInt(computedStyle.paddingBottom); // 设置高度:scrollHeight减去上下内边距,只保留内容实际高度 autoResizeTextarea.style.height = `${autoResizeTextarea.scrollHeight - paddingTop - paddingBottom}px`; } // 绑定输入事件,实时调整高度 autoResizeTextarea.addEventListener('input', adjustTextareaHeight); // 页面加载时初始化高度 adjustTextareaHeight();
额外注意点
- 如果你的textarea有特殊的行高或者字体设置,一定要在CSS里明确写出来,不要依赖浏览器默认值,否则不同浏览器的计算结果会有偏差。
- 测试删除内容的场景:当你把所有内容删掉,或者从多行删回单行时,这个逻辑会自动把高度收缩回单行,完全符合预期。
内容的提问来源于stack exchange,提问作者Ascendant
相关产品推荐
相关产品推荐

