想法是使 <textarea>
更像 <div>
,所以它的高度能夠擴展以包含當前值。這幾乎是奇怪的,沒有一個簡單的原生解決方案,不是嗎?css
如今我獲得了一個很是好的原生解決方案。html
這裏是演示,若是你只是想要一個工做的例子安全
<h1>Auto-Growing <code><textarea></code></h1> <form action="#0"> <label for="text">Text:</label> <div class="grow-wrap"> <textarea name="text" id="text" onInput="this.parentNode.dataset.replicatedValue = this.value"></textarea> </div> </form>
.grow-wrap { /* 簡單的方法將元素疊加在一塊兒,並根據最高者的高度肯定它們的大小。 */ display: grid; } .grow-wrap::after { /* 注意奇怪的空間!須要預防跳動行爲 */ content: attr(data-replicated-value) " "; /* 這就是textarea文本的表現形式 */ white-space: pre-wrap; /* 隱藏在視圖,點擊和屏幕閱讀器中 */ visibility: hidden; } .grow-wrap > textarea { /* 您能夠保留此設置,可是在用戶調整大小後,它將破壞自動調整大小 */ resize: none; /* Firefox顯示增加的滾動條,您能夠像這樣隱藏。 */ overflow: hidden; } .grow-wrap > textarea, .grow-wrap::after { /* 須要相同的樣式! */ border: 1px solid black; padding: 0.5rem; font: inherit; /* 放在彼此之上 */ grid-area: 1 / 1 / 2 / 2; } body { margin: 2rem; font: 1rem/1.4 system-ui, sans-serif; } label { display: block; }
效果字體
訣竅是,你要準確地將 <textarea>
的內容複製到一個能夠自動展開高度的元素中,並匹配它的大小。ui
因此你有一個 <textarea>
,它不能自動展開高度。this
相反,您能夠在另外一個元素中徹底複製該元素的外觀,內容和位置,再複製的元素隱藏起來。spa
如今,這三個元素都是相互聯繫的。不管哪個子元素最高,都會把父元素推到那個高度,而另外一個子元素也會跟隨。這意味着 <textarea>
的最小高度將成爲「基礎」高度,可是若是複製的文本元素碰巧變高了,全部的東西也會隨之變高。code
好聰明,我太喜歡了。orm
您須要確保複製的元素徹底相同htm
相同的字體,相同的填充,相同的頁邊距,相同的邊框...全部內容。這是一個相同的副本,只是在視覺上隱藏了 visibility: hidden;
;若是不是徹底同樣的,那麼全部的東西都不會徹底正確地生長在一塊兒。
咱們還須要在複製的文本上 white-space: pre-wrap;
,由於這就是textareas的表現。
這是最奇怪的部分
在個人演示中,我將 ::after
用於複製的文本。我不肯定這是不是最好的方法。對我來講感受很乾淨,可是我想知道使用 <div aria-hidden =「 true」>
對於屏幕閱讀器是否更安全?
或 visibility: hidden;
夠了嗎?不管如何,那不是奇怪的部分。這是奇怪的部分:
content: attr(data-replicated-value) " ";
由於我使用的是僞元素,僞元素是將 data
屬性從元素中取出並以額外的空間將內容呈現到頁面的行(這是奇怪的部分)。若是你不這樣作,最終的結果會讓人感受 "跳脫"。我不能說我徹底理解它,但它彷佛更好地尊重了跨textarea和文本元素的換行行爲。
若是你不想使用僞元素,嘿嘿,我沒意見,只要注意跳動的行爲便可。