Automatically expand a textarea as the user types using vanilla JavaScript
Tommy Hodgins shared a really neat little helper function with me that automatically expands a textarea as the user types in.
I made a few modifications to simplify it down a bit, and wanted to share it with you and how it works.
The HTML
All you need in the way of markup for this is a humble textarea
element.
<textarea></textarea>
The CSS
I give my textarea’s just a little bit of styling.
A min-height
ensures that at least a few lines of text show up to start. A max-height
of 50vh
ensures the text area will never grow bigger than the viewport. I also like to add a width
of 100%
so that the text area fills up the full width of the content area.
textarea {
min-height: 5em;
max-height: 50vh;
width: 100%;
}
The JavaScript
Here’s the fun part.
Listening for changes to textareas
First, let’s setup an event listener to detect changes to our textarea
element. We’ll use event delegation to listen to all input
events and then filter out ones that aren’t on a textarea.
document.addEventListener('input', function (event) {
if (event.target.tagName.toLowerCase() !== 'textarea') return;
}, false);
If the element is a textarea, we’ll call a new function we’re going to create, autoExpand()
, and pass in the element as an argument using event.target
.
document.addEventListener('input', function (event) {
if (event.target.tagName.toLowerCase() !== 'textarea') return;
autoExpand(event.target);
}, false);
Auto-expanding the textarea
Now, we can setup our autoExpand()
function.
var autoExpand = function (field) {
// Do things...
};
First, we need to reset the height of the textarea so that we can calculate how tall the content is/should be.
var autoExpand = function (field) {
// Reset field height
field.style.height = 'inherit';
};
To calculate our height, we need to get both the height of the content, and any borders and padding on the textarea that will affect its overall height.
We’ll use window.getComputedStyle()
to get styles for the textarea, and scrollHeight
to calculate the height of the content itself.
We’ll run all of the values through parseInt()
to convert them to integers, and then add them up to get our total element height.
// Get the computed styles for the element
var computed = window.getComputedStyle(field);
// Calculate the height
var height = parseInt(computed.getPropertyValue('border-top-width'), 10)
+ parseInt(computed.getPropertyValue('padding-top'), 10)
+ field.scrollHeight
+ parseInt(computed.getPropertyValue('padding-bottom'), 10)
+ parseInt(computed.getPropertyValue('border-bottom-width'), 10);
Finally, we’ll set the height of our element using the style
property.
var autoExpand = function (field) {
// Reset field height
field.style.height = 'inherit';
// Get the computed styles for the element
var computed = window.getComputedStyle(field);
// Calculate the height
var height = parseInt(computed.getPropertyValue('border-top-width'), 10)
+ parseInt(computed.getPropertyValue('padding-top'), 10)
+ field.scrollHeight
+ parseInt(computed.getPropertyValue('padding-bottom'), 10)
+ parseInt(computed.getPropertyValue('border-bottom-width'), 10);
field.style.height = height + 'px';
};
And that’s it! You can view a working demo here.
Browser Compatibility
This will work in all modern browsers, and IE9 and up. Thanks Tommy!