自动增长Textareas的最干净技巧web前端开发关注共 1720字,需浏览 4分钟 ·2020-12-23 11:19 翻译 | https://blog.zhangbing.site/2020/12/02/the-cleanest-trick-for-autogrowing-textareas/原文 | https://css-tricks.com/想法是使 更像 <div>,因此它的高度可以扩展以包含当前值。这几乎是奇怪的,没有一个简单的原生解决方案,不是吗?<br></span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">现在我得到了一个非常好的原生解决方案。</span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">这里是演示,如果你只是想要一个工作的例子。</span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">html:</span></p><pre><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="xml"><code><span class="code-snippet_outer"><span class="code-snippet__tag"><<span class="code-snippet__name">h1</span>></span>Auto-Growing <span class="code-snippet__tag"><<span class="code-snippet__name">code</span>></span><textarea><span class="code-snippet__tag"></<span class="code-snippet__name">code</span>></span><span class="code-snippet__tag"></<span class="code-snippet__name">h1</span>></span></span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag"><<span class="code-snippet__name">form</span> <span class="code-snippet__attr">action</span>=<span class="code-snippet__string">"#0"</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">label</span> <span class="code-snippet__attr">for</span>=<span class="code-snippet__string">"text"</span>></span>Text:<span class="code-snippet__tag"></<span class="code-snippet__name">label</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">div</span> <span class="code-snippet__attr">class</span>=<span class="code-snippet__string">"grow-wrap"</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"><<span class="code-snippet__name">textarea</span></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attr">name</span>=<span class="code-snippet__string">"text"</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attr">id</span>=<span class="code-snippet__string">"text"</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attr">onInput</span>=<span class="code-snippet__string">"this.parentNode.dataset.replicatedValue = this.value"</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet_outer"> ></span><span class="code-snippet__tag"></<span class="code-snippet__name">textarea</span>></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__tag"></<span class="code-snippet__name">div</span>></span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag"></<span class="code-snippet__name">form</span>></span></span></code></pre></section></pre><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="text-align: justify;font-size: 16px;"><span style="color:#000000;">CSS:</span></span><span style="color: rgb(155, 112, 63);font-size: 14px;text-align: justify;"></span></p><pre><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><pre class="code-snippet__js" data-lang="css"><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.grow-wrap</span> {</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">/* 简单的方法将元素叠加在一起,并根据最高者的高度确定它们的大小。*/</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attribute">display</span>: grid;</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.grow-wrap</span><span class="code-snippet__selector-pseudo">::after</span> {</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">/* 注意奇怪的空间!需要预防跳动行为 */</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attribute">content</span>: <span class="code-snippet__built_in">attr</span>(>) <span class="code-snippet__string">" "</span>;</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">/* 这就是textarea文本的表现形式 */</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attribute">white-space</span>: pre-wrap;</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">/* 隐藏在视图,点击和屏幕阅读器中 */</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attribute">visibility</span>: hidden;</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.grow-wrap</span> > <span class="code-snippet__selector-tag">textarea</span> {</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">/* 您可以保留此设置,但是在用户调整大小后,它将破坏自动调整大小 */</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attribute">resize</span>: none;</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">/* Firefox显示增长的滚动条,您可以像这样隐藏。*/</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attribute">overflow</span>: hidden;</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.grow-wrap</span> > <span class="code-snippet__selector-tag">textarea</span>,</span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-class">.grow-wrap</span><span class="code-snippet__selector-pseudo">::after</span> {</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">/* 需要相同的样式!*/</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attribute">border</span>: <span class="code-snippet__number">1px</span> solid black;</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attribute">padding</span>: <span class="code-snippet__number">0.5rem</span>;</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attribute">font</span>: inherit;</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__comment">/* 放在彼此之上 */</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attribute">grid-area</span>: <span class="code-snippet__number">1</span> / <span class="code-snippet__number">1</span> / <span class="code-snippet__number">2</span> / <span class="code-snippet__number">2</span>;</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">body</span> {</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attribute">margin</span>: <span class="code-snippet__number">2rem</span>;</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attribute">font</span>: <span class="code-snippet__number">1rem</span>/<span class="code-snippet__number">1.4</span> system-ui, sans-serif;</span></code><code><span class="code-snippet_outer">}</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"><span class="code-snippet__selector-tag">label</span> {</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attribute">display</span>: block;</span></code><code><span class="code-snippet_outer">}</span></code></pre></section></pre><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">效果:</span></p><p style="color: rgb(85, 85, 85);font-family: "Helvetica Neue", "Segoe UI", "Hiragino Sans GB", "Microsoft YaHei", Verdana, sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><br></p><p><img data-ratio="0.7682291666666666" src="https://filescdn.proginn.com/3187c6f3301251df5321770b930685db/e4bb9cf967bd62d23dc2973cbc534258.webp" data-type="gif" data-w="768"></p><p style="color: rgb(85, 85, 85);font-family: "Helvetica Neue", "Segoe UI", "Hiragino Sans GB", "Microsoft YaHei", Verdana, sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><br></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">诀窍是,你要准确地将 <textarea> 的内容复制到一个可以自动展开高度的元素中,并匹配它的大小。</span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">所以你有一个 <textarea>,它不能自动展开高度。</span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">相反,您可以在另一个元素中完全复制该元素的外观,内容和位置,再复制的元素隐藏起来。</span></p><p style="color: rgb(85, 85, 85);font-family: "Helvetica Neue", "Segoe UI", "Hiragino Sans GB", "Microsoft YaHei", Verdana, sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><br></p><p><img data-ratio="0.6680497925311203" src="https://filescdn.proginn.com/021a4f495d43ed1bf50fef46fa0af533/fb6de1c4585825133592db6127c0564f.webp" data-type="jpeg" data-w="723"><br></p><p style="color: rgb(85, 85, 85);font-family: "Helvetica Neue", "Segoe UI", "Hiragino Sans GB", "Microsoft YaHei", Verdana, sans-serif;font-size: medium;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><br></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">现在,这三个元素都是相互联系的。无论哪一个子元素最高,都会把父元素推到那个高度,而另一个子元素也会跟随。这意味着 <textarea> 的最小高度将成为“基础”高度,但是如果复制的文本元素碰巧变高了,所有的东西也会随之变高。</span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">好聪明,我太喜欢了。</span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">您需要确保复制的元素完全相同</span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">相同的字体,相同的填充,相同的页边距,相同的边框…所有内容。这是一个相同的副本,只是在视觉上隐藏了 visibility: hidden;;如果不是完全一样的,那么所有的东西都不会完全正确地生长在一起。</span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">我们还需要在复制的文本上 white-space: pre-wrap; ,因为这就是 textareas 的表现。</span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">这是最奇怪的部分</span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">在我的演示中,我将 ::after 用于复制的文本。我不确定这是否是最好的方法。对我来说感觉很干净,但是我想知道使用 <div aria-hidden =“ true”> 对于屏幕阅读器是否更安全?</span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">或 visibility: hidden; 够了吗?无论如何,那不是奇怪的部分。这是奇怪的部分:</span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">css</span></p><pre><section class="code-snippet__fix code-snippet__js"><ul class="code-snippet__line-index code-snippet__js"><li></li></ul><pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer">content: attr(>) <span class="code-snippet__string">" "</span>;</span></code></pre></section></pre><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">因为我使用的是伪元素,伪元素是将 data 属性从元素中取出并以额外的空间将内容呈现到页面的行(这是奇怪的部分)。如果你不这样做,最终的结果会让人感觉 “跳脱”。我不能说我完全理解它,但它似乎更好地尊重了跨 textarea 和文本元素的换行行为。</span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">如果你不想使用伪元素,嘿嘿,我没意见,只要注意跳动的行为即可。</span></p><p style="text-align: left;margin-top: 15px;margin-bottom: 15px;"><span style="font-size: 16px;color: rgb(0, 0, 0);">完整示例和代码:https://codepen.io/chriscoyier/pen/XWKEVLy</span></p><section style="margin-right: 8px;margin-left: 8px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"><span style="font-size: 16px;color: rgb(0, 0, 0);"><span style="vertical-align: inherit;"><span style="vertical-align: inherit;">本文完〜</span></span></span></section><section style="margin-right: 8px;margin-left: 8px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"><br></section><section style="margin-right: 8px;margin-left: 8px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"><img class="rich_pages" data-ratio="0.044444444444444446" data-s="300,640" data-type="jpeg" data-w="900" src="https://filescdn.proginn.com/d9ba959cb95917191d40da5c723f9344/1d1d9e2916c7ee36a6b420ca7adc1fe1.webp" style="box-sizing: border-box !important;visibility: visible !important;width: 677px !important;"></section><section style="margin-right: 8px;margin-left: 8px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;"></section><p><br></p><p><br></p> </div></div></div><div class="tag-list-box"><div class="tag-list"><div class="tag-list-container"></div></div></div><span class="view_num">浏览 22</span><div class="float-bar float-bar-relative" id="float-bar-relative"><div class="float-bar-body"><div class="item qinglite-zan"><i class="iconfont icon-aixin"></i>点赞 </div><div class="gap"></div><a href="#comments" class="item"><i class="iconfont iconfont icon-pinglun1"></i><span class="com_num"></span>评论 </a><div class="item qinglite-collect"><i class="iconfont icon-shoucang"></i>收藏 </div><div class="item qinglite_share"><i class="iconfont icon-fenxiang1"></i>分享 <div class="qrcode-modal"><img src="/api/pub/ewm" alt=""><p>手机扫一扫分享</p></div></div><div class="expand"></div><a onclick="miniProgram_navigateTo_func()" class="item qinglite_share_miniapp miniapp_show"><i class="iconfont icon-fenxiang1"></i>分享 </a><div class="item jubao qinglite-jubao miniapp_hide"><i class="iconfont icon-jubao"></i> 举报 </div></div></div></div><div class="comments_wrapper comments app_hide"><div class="title">评论</div><div id="comments" class="comments"><div class="error"></div><div class="textarea-wrapper"><textarea class="comment-content" cols="30" rows="5" placeholder="善语结善缘,恶言伤人心">图片表情视频评价全部评论推荐 Auto Growing TextareasThis plugin makes it easy to have auto-growing texAuto Growing TextareasThispluginmakesiteasytohaveauto-growingtextareas.Meaning,ifyouhaveatextarea,astheusertypesitwillexpaIDEA 自动补全技巧Java项目开发0atomic-chromeEdit Chrome textareas in AtomAtomic ChromeUse Atom to edit in ChromeScreencastGJupyter Notebook最常用的五大配置技巧Python爬虫与数据挖掘0最实用的薪资谈判技巧,求职必不可少!产品管理CLUB0atomic-chrome-atomEdit Chrome textareas in AtomAtomicChromeUseAtomtoeditinChromeScreencastGitHubissue(textarea)Gmail(contenteditable)InstallationYoJupyter Notebook最常用的五大配置技巧Python大数据分析0atomic-chrome-atomEdit Chrome textareas in AtomAtomic ChromeUse Atom to edit in ChromeScreencastGatomic-chromeEdit Chrome textareas in AtomAtomicChromeUseAtomtoeditinChromeScreencastGithubissue(textarea)Gmail(contenteditable)InstallationYo点赞 评论 收藏 分享 手机扫一扫分享分享 举报