Great post! I recently stumbled across this problem when designing a website. Solved it with one of those keyup solutions; was never really happy about it. This will definitely fix it! Thanks.
Copy & paste the code below to embed this comment.
Nate Vaughn
I read this article on the bus commute, didn’t seem to be working on iPhone 4, pre iOS5 update. Excellent technique however. Looking forward to blasting the future with awesome textareas.
I really like this technique – it is better than a lot of the others I have seen. I threw together a jQuery plugin version based on your code that limits the amount of extra CSS and handles some of the cross browser issues, while automatically initializing textareas with an ‘expanding’ class on load:
The other thing it does is attempt to gather any possible CSS from the textarea for things like font and spacing when initializing the mirror ‘pre’ tag. This is helpful in case there are properties that you don’t remember or know about resetting for both the ‘pre’ and the ‘textarea’. Obviously, this doesn’t work for percentage paddings and widths, etc – it is still best to define rules for both at the same time, but it might make it a little easier to drop into an existing system if it handles CSS rules that cascaded down to either the textarea or pre.
Note: I haven’t really tested this in IE. You mentioned the onpropertychange event not delegating properly: jQuery may or may not handle that transparently.
@bgrins, thought about making a GitHub Repository for your plugin? I was thinking of making one for it, but I don’t want to copy your code if you are going to make one.
I’m sure this would be an easy tweak in the code but it seems like if you’re going to have an expanding text area you should always have more than one line to start with so someone knows up front that they are able to put in more than one line of text, otherwise as they type the might cut it short before they realize that more lines can be added…
@aBrentApart, a simple way to do this would be to add a min-height property to your CSS for the element that controls the height of the textarea.
If you did a min-height: 2em; (adjust for your line-height) then it would start off with two rows of height and would start adjusting once you are over two lines.
Copy & paste the code below to embed this comment.
Neil Jenkins
As @Zoram said, you can specify a min-height to make it initially 2 (or whatever) lines in height and then always fit exactly to the content as it expands past that. To make it always be one line taller than the content, just add an extra
inside the <pre> element. Whether you want to do either of these things will depend on the circumstances; in some constrained places like a smartphone app, or where you have lots of text areas together in a small space you may want them to start at only 1 line’s height. In other situations, you probably want them to be 2 or 3 lines in height to begin with to let the user know they can enter more than one line of text.
@Neil, exactly. In the demo for the plugin that bgrins setup you can see an example of single line or multiple line starting heights all controlled by the CSS:
http://bgrins.github.com/ExpandingTextareas/
You could use media queries to also change the number of lines depending upon the screen size/functionality.
I have made a Dutch translation from this article.
Viewable at http://www.mastercode.nl/forum/artikelen-javascript/verlengbare-tekstvelden-netjes-gemaakt-t2205.html
Doesn’t seem to work. Replication: (type or copy and paste)
“i am the waterman see what i can do queen of all that is right and soo the man with the can did what he can and saw what he saw but only if there was a law but there wasn’t and now”
Good Post! Your post is an excellent example of why I keep comming back to read your excellent quality content that is forever updated. More please, this post helped me consider a few more things, keep up the good work.
And I have a online fashion , if you have interest , welcome to go and have a look .
Copy & paste the code below to embed this comment.
Neil Jenkins
@slapzstick. It appears Firefox (at least on Mac) is adding an extra 1px padding to the text area in addition to whatever you specify; this means with certain inputs (such as your example text), the text in the text area will wrap a word before the pre does, so it gets out of sync. As a workaround, you can add a Firefox-only padding property to the text area (this will be ignored by other browsers:
padding: -moz-calc( 5px ) -moz-calc( 4px );
That fixes it. Strange, and annoying, bug in Firefox though.
Copy & paste the code below to embed this comment.
Forma
Looks great, but what about accessibility? Wouldn’t it be confusing to people who use screen readers to have their text appear twice? (assuming that’s what would happen, i admit i do not know that much about accessibility software)
Copy & paste the code below to embed this comment.
stalkov
Wow. Thank you very much for this amazing form enhancement! For anyone inclined to use jQuery, here is a jQuery version I derived from the Javascript used in this example. Of course all the HTML and CSS in the example would stay the same.
$(function() {
$(‘div.expandingArea’).each(function() {
var area = $(‘textarea’, $(this));
var span = $(‘span’, $(this));
area.bind(‘input’, function() { span.text(area.val()); });
span.text(area.val());
$(this).addClass(‘active’);
});
});
A few words about syntax highlighting.
I tried this approach but had an issue with differences in line breaking between TextArea and HTMLElement. See http://jsfiddle.net/QrZHM/1/ – change width of the window and you will get differences like I have http://cl.ly/2z3F3T1B270k1B1f1432
That’s pretty cool. I will try it today. Came in just as called for since I am actually playing with some website setup for smart phones right now. Could use it for contact page. Thanks for sharing.
Copy & paste the code below to embed this comment.
Neil Jenkins
kigorw This is the same problem slapzstick came across; in Firefox (only), it appears there’s a hidden 1px extra horizontal padding added to textareas which you can’t remove. See my comment 17 for a suggested fix.
@jsturgis Hmm, I’ve had it working fine in iOS4 before, but unfortunately I now only have iOS5 devices so can no longer test and see what’s happening there. My guess, given that you say you can’t adjust the padding, is that the styles on the textarea are being overridden to the platform defaults. Adding the CSS “-webkit-apparance: none” to the textarea might well fix it.
Nice idea. Unfortunately, as 11% of the users of the sites I administer still use IE7 (9%) or IE6 (2%) I won’t be using it. However, I like the concept of breaking free from the bog standard textarea, so I will definately be bearing your work in mind in the future.
Copy & paste the code below to embed this comment.
MikeDepies
When I run your version on IE it works fine. However, when I run my copied code version locally IE throws up errors for document object not having the method querySelectorsAll. Anything I might be overlooking?
I stumbled upon this most excellent approach to an expandable textarea. I decided to make a YUI version. It includes support for minimum and maximum height settings.
28 Reader Comments
Back to the Articleiasmatt
Great post! I recently stumbled across this problem when designing a website. Solved it with one of those keyup solutions; was never really happy about it. This will definitely fix it! Thanks.
Nate Vaughn
I read this article on the bus commute, didn’t seem to be working on iPhone 4, pre iOS5 update. Excellent technique however. Looking forward to blasting the future with awesome textareas.
bgrins
I really like this technique – it is better than a lot of the others I have seen. I threw together a jQuery plugin version based on your code that limits the amount of extra CSS and handles some of the cross browser issues, while automatically initializing textareas with an ‘expanding’ class on load:
“http://jsfiddle.net/bgrins/UA7ty”:http://jsfiddle.net/bgrins/UA7ty/
The other thing it does is attempt to gather any possible CSS from the textarea for things like font and spacing when initializing the mirror ‘pre’ tag. This is helpful in case there are properties that you don’t remember or know about resetting for both the ‘pre’ and the ‘textarea’. Obviously, this doesn’t work for percentage paddings and widths, etc – it is still best to define rules for both at the same time, but it might make it a little easier to drop into an existing system if it handles CSS rules that cascaded down to either the textarea or pre.
Note: I haven’t really tested this in IE. You mentioned the onpropertychange event not delegating properly: jQuery may or may not handle that transparently.
Zoram
@bgrins, thought about making a GitHub Repository for your plugin? I was thinking of making one for it, but I don’t want to copy your code if you are going to make one.
bgrins
Zoram, sure. I have created the github repository at: “https://github.com/bgrins/ExpandingTextareas”:https://github.com/bgrins/ExpandingTextareas
As I said, IE is not yet supported, but I will update it when I get a chance to test IE.
aBrentApart
I’m sure this would be an easy tweak in the code but it seems like if you’re going to have an expanding text area you should always have more than one line to start with so someone knows up front that they are able to put in more than one line of text, otherwise as they type the might cut it short before they realize that more lines can be added…
Zoram
@aBrentApart, a simple way to do this would be to add a min-height property to your CSS for the element that controls the height of the textarea.
If you did a min-height: 2em; (adjust for your line-height) then it would start off with two rows of height and would start adjusting once you are over two lines.
Neil Jenkins
As @Zoram said, you can specify a min-height to make it initially 2 (or whatever) lines in height and then always fit exactly to the content as it expands past that. To make it always be one line taller than the content, just add an extra
inside the <pre> element. Whether you want to do either of these things will depend on the circumstances; in some constrained places like a smartphone app, or where you have lots of text areas together in a small space you may want them to start at only 1 line’s height. In other situations, you probably want them to be 2 or 3 lines in height to begin with to let the user know they can enter more than one line of text.
Zoram
@Neil, exactly. In the demo for the plugin that bgrins setup you can see an example of single line or multiple line starting heights all controlled by the CSS:
http://bgrins.github.com/ExpandingTextareas/
You could use media queries to also change the number of lines depending upon the screen size/functionality.
Thierry Koblentz
I don’t think IE needs the prefix here:
-ms-box-sizing: border-box;
Neil Jenkins
IE9 may not, but I believe IE8 does require the ms prefix for the box-sizing property.
Thierry Koblentz
@Neil:
No it does not. Check: “caniuse.com”:http://caniuse.com/#search=box-sizing
It should not be a surprise though. After all, it’s Microsoft who invented the broken box model ;)
Zunflappie
I have made a Dutch translation from this article.
Viewable at http://www.mastercode.nl/forum/artikelen-javascript/verlengbare-tekstvelden-netjes-gemaakt-t2205.html
I hope its allowed to do so.
slapzstick
Doesn’t seem to work. Replication: (type or copy and paste)
“i am the waterman see what i can do queen of all that is right and soo the man with the can did what he can and saw what he saw but only if there was a law but there wasn’t and now”
resizes after a couple more chars are entered.
slapzstick
Actually doesn’t seem to work for any text, for the first couple chars using the sample box in the article.
online-fashion
Good Post! Your post is an excellent example of why I keep comming back to read your excellent quality content that is forever updated. More please, this post helped me consider a few more things, keep up the good work.
And I have a online fashion , if you have interest , welcome to go and have a look .
Neil Jenkins
@slapzstick. It appears Firefox (at least on Mac) is adding an extra 1px padding to the text area in addition to whatever you specify; this means with certain inputs (such as your example text), the text in the text area will wrap a word before the pre does, so it gets out of sync. As a workaround, you can add a Firefox-only padding property to the text area (this will be ignored by other browsers:
padding: -moz-calc( 5px ) -moz-calc( 4px );
That fixes it. Strange, and annoying, bug in Firefox though.
Forma
Looks great, but what about accessibility? Wouldn’t it be confusing to people who use screen readers to have their text appear twice? (assuming that’s what would happen, i admit i do not know that much about accessibility software)
stalkov
Wow. Thank you very much for this amazing form enhancement! For anyone inclined to use jQuery, here is a jQuery version I derived from the Javascript used in this example. Of course all the HTML and CSS in the example would stay the same.
$(function() {
$(‘div.expandingArea’).each(function() {
var area = $(‘textarea’, $(this));
var span = $(‘span’, $(this));
area.bind(‘input’, function() { span.text(area.val()); });
span.text(area.val());
$(this).addClass(‘active’);
});
});
kigorw
A few words about syntax highlighting.
I tried this approach but had an issue with differences in line breaking between TextArea and HTMLElement. See http://jsfiddle.net/QrZHM/1/ – change width of the window and you will get differences like I have http://cl.ly/2z3F3T1B270k1B1f1432
djarzyna
That’s pretty cool. I will try it today. Came in just as called for since I am actually playing with some website setup for smart phones right now. Could use it for contact page. Thanks for sharing.
jsturgis
@Neil, Hi nice solution but it doesn’t work for mobile safari on IOS < 5. The pre text lags a little behind the textarea text.
“text offset screenshot with pre visible”:https://s3-us-west-1.amazonaws.com/sturgisweb-portfolio/public/ios1.png
“text wraps before textarea grows screenshot”:https://s3-us-west-1.amazonaws.com/sturgisweb-portfolio/public/ios2.png
Any ideas on how to fix this? adjusting padding and letter-spacing doesn’t work.
Neil Jenkins
kigorw This is the same problemslapzstick came across; in Firefox (only), it appears there’s a hidden 1px extra horizontal padding added to textareas which you can’t remove. See my comment 17 for a suggested fix.@jsturgis Hmm, I’ve had it working fine in iOS4 before, but unfortunately I now only have iOS5 devices so can no longer test and see what’s happening there. My guess, given that you say you can’t adjust the padding, is that the styles on the textarea are being overridden to the platform defaults. Adding the CSS “-webkit-apparance: none” to the textarea might well fix it.
Maurice
@Neil, How about adding text-indent: -moz-calc(-1px) to the textarea instead of altering the padding? Seems to work fine in Firefox 8 for Windows.
puzbie
Nice idea. Unfortunately, as 11% of the users of the sites I administer still use IE7 (9%) or IE6 (2%) I won’t be using it. However, I like the concept of breaking free from the bog standard textarea, so I will definately be bearing your work in mind in the future.
MikeDepies
When I run your version on IE it works fine. However, when I run my copied code version locally IE throws up errors for document object not having the method querySelectorsAll. Anything I might be overlooking?
mschipperheyn
Hi,
I stumbled upon this most excellent approach to an expandable textarea. I decided to make a YUI version. It includes support for minimum and maximum height settings.
http://yuilibrary.com/gallery/show/textarea-expander
Let me know if you have suggestions.
Cheers,
Marc
njaggars
It looks like the demo broke some time in the last year (the quotes in the script have been replaced with their HTML entity equivalent).