Reputation: 7466
I would like to have a text area which is always as big as the text in it. So the page can be scrolled and in the text area cannot be scrolled.
Here's what I did until now:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
html, body {height: 100%;}
textarea {
border: none;
width: 100%;
height: 100%;
-webkit-box-sizing: border-box;
line-height: 44px;
font-family:Helvetica;
font-size: 17pt;
-webkit-tap-highlight-color: rgba(0,0,0,0);
background-image:url('[email protected]');
outline: none;
resize: none;
}
textarea.vert { resize:vertical; }
</style></head><body>
<textarea id="InputTextArea" placeholder="placeholder"></textarea>
</body></html>
Upvotes: 15
Views: 44331
Reputation: 74
<textarea
id="newComm"
class="form-control"
name="comment"
placeholder="Some text"
cols="30"
:rows="rowsHeight"
wrap="soft"
v-model.trim="newCommText"
@input="changeRows"
:style="'resize: none; overflow: hidden; line-height: '+lineHeight+'px;'"
></textarea>
setup() {
const newCommText = ref(null)
const rowsHeightStart = ref(5)
const rowsHeight = ref(rowsHeightStart.value)
const lineHeight = ref(25)
function changeRows (event) {
rowsHeight.value = event.target.value.split("\n").length > rowsHeightStart.value ? event.target.value.split("\n").length : rowsHeightStart.value
}
return {
rowsHeight, lineHeight, newCommText,
changeRows
}
Upvotes: 0
Reputation: 2747
Just setting height = scrollHeight
misses the goal when box-sizing: border-box
is set. Here is a solution with a fix for that and which allows the textarea to shrink again.
// auto resize the textareas
document.querySelectorAll("textarea").forEach(function (el) {
el.addEventListener("input", function () {
var cs = window.getComputedStyle(this);
// reset height to allow textarea to shrink again
this.style.height = "auto";
// when "box-sizing: border-box" we need to add vertical border size to scrollHeight
this.style.height = (this.scrollHeight + parseInt(cs.getPropertyValue("border-top-width")) + parseInt(cs.getPropertyValue("border-bottom-width"))) + "px";
});
});
// compat window.getComputedStyle: IE9
// compat NodeList.forEach: No IE (but not necessary here)
* { box-sizing: border-box; }
textarea { width: 20%; }
#a { padding: 1em; }
#b { padding: 0; }
#c { max-height: 7em; }
#d {
border-top: 10px solid blue;
border-bottom: 10px solid blue;
}
<textarea id="a">1em padding</textarea>
<textarea id="b">0 padding</textarea>
<textarea id="c">max-height: 7em</textarea>
<textarea id="d">10px vertical borders</textarea>
Upvotes: 0
Reputation: 3792
If someone need a solution for Vue.js. Here is a vue directive to do a auto resizing text area. Just register directive globally once and you can use it for any textarea
Vue.directive('resizable', {
inserted: function (el) {
el.addEventListener('input', function(e) {
e.target.style.height = "auto";
e.target.style.height = e.target.scrollHeight + 'px';
});
}
});
html is easy, just put v-resizable attribute in textarea
<textarea v-resizable></textarea>
Special thanks to AniMir! I am using his input event handler.
Upvotes: 2
Reputation: 160
In case anyone still needs this, for what it's worth, here's mine in pure js. But first, you may check this one: Auto expand a textarea using jQuery
var textAreas = document.getElementsByTagName('textarea');
try {
taLength = textAreas.length;
for (i=0; i < taLength; i++) {
var taId = textAreas[i].id;
document.getElementById(taId).addEventListener('input', function(e) {
e.target.style.height = "auto";
//This makes your textarea back to its original size. So you can replace it with any size you want it to have e.g. "120px"
//You may need some logic if you have multiple taxtareas with different original sizes
e.target.style.height = e.target.scrollHeight+'px';
});
}
}
catch (err) {
window.alert(err);
}
I used shubhra's answer to build that one. It is smooth and the scrollbar won't appear.
Upvotes: 2
Reputation: 3898
If you are using AngularJS, you can do :
<textarea ng-keyup="ctl.handleTextAreaHeight($event)"></textarea>
With this in your controller :
this.handleTextAreaHeight = function (e) {
var element = e.target;
element.style.overflow = 'hidden';
element.style.height = 0;
element.style.height = element.scrollHeight + 'px';
};
Upvotes: 2
Reputation: 782
Resizing TeaxArea based on the content line number. Here's a DEMO
JS
function resizeTextarea (id) {
var a = document.getElementById(id);
a.style.height = 'auto';
a.style.height = a.scrollHeight+'px';
}
function init() {
var a = document.getElementsByTagName('textarea');
for(var i=0,inb=a.length;i<inb;i++) {
if(a[i].getAttribute('data-resizable')=='true')
resizeTextarea(a[i].id);
}
}
addEventListener('DOMContentLoaded', init);
HTML
<textarea id="InputTextArea" placeholder="placeholder" onkeyup="resizeTextarea('InputTextArea')"></textarea>
Upvotes: 16