I remember googling for something of this nature a while ago but all I found were countless attempts using the cols and/or rows attribute of the textarea, thus making it pretty useless if you weren’t using a fixed-width font.
Inspired by Jason Frame’s method, I’ve created an animating ‘autoResize’ jQuery plugin. Although it was inspired by his plugin it has a few slight differences, most notably the way in which the off-screen "testing" takes place. In his plugin (apparently inspired by Facebook’s implementation) a DIV is created off-screen and is filled with the textarea’s value whenever it changes. The height of this DIV is retrieved and then applied to the textarea. My plugin makes use of the scrollTop DOM property to gain the true height of the text and then applies that directly (or via animation) to the textarea.
Demo
Note: this demo only works if you have JavaScript enabled!
Usage
The following options are available:
- onResize - (type: Function) - A callback function fired every time the textarea is resized. Within the function 'this' refers to the textarea being resized.
- animate - (type: Boolean) - If set to
falseno animation will take place, the height will immediately change when necessary. By default it's set totrue. - animateDuration - (type: Number) - Millisecond duration of animation, by default it's set to
150. - animateCallback - (type: Function) - A callback function fired every time an animation completes. Note: not the same as the
onResizecallback. - extraSpace - (type: Number) - A pixel value to be added to the total necessary height when applied to the textarea. By default it's set to 20. The idea behind this is to reassure users that they have more space to continue writing.
- limit - (type: Number) - Once the textarea reaches this height it will stop expanding. By default it's set to 1000.
The textarea will expand when required until the limit is reached, at which time it brings back the scrollbar. If you were to then delete all the contents of the textarea it would only return to it's original size (no smaller). Also note that, even if you set 'animate' to true, the animation will only occur if the element is set to display:block; in the CSS.
An example implementation:
$('textarea#comment').autoResize({ // On resize: onResize : function() { $(this).css({opacity:0.8}); }, // After resize: animateCallback : function() { $(this).css({opacity:1}); }, // Quite slow animation: animateDuration : 300, // More extra space: extraSpace : 40 });
The plugin has been tested successfully in IE6/7, FF2/3, Opera9, Safari3 & Chrome.
Download
- Full: autoresize.jquery.js [~4k]
- Minified: autoresize.jquery.min.js [~1k]
- jQuery 1.3: jquery.min.js
James… This rocks and totally great timing I know just where to use this. Thanks.
this is very useful – thanks for sharing!
This is totally awesome! It’s perfect for editing large amounts of text.
I think I love you! Lol, jk.
great plugin !!
just to understand, what’s “.dynSiz” anf what exactly does “keyup.dynSiz”
thanks !
Yes! I was looking for something like this the other day and was JUST about to wrap my head around it and make it… guess i’ll study your code instead. cheers
Bookmarked! Excellent work James. I’m loving this. I’m going to have to utilize this in future CMS projects. Sure beats the old scroll bar.
Does it default to a scroll bar if Javascript is disabled?
Thanks a lot James! I can use this in my current project! Again, Thanks!
Thanks for the comments!
@riper, the ‘.dynSiz’ part is a namespace. When binding event handlers jQuery allows you to namespace certain events which makes it easier to remove them all at once. It’s especially useful when creating a plugin! For example:
@Branden, yep, it degrades gracefully without JavaScript.
thanks for the explanation, very useful.
btw, i coded something similar some weeks ago for a project i did to learn rails (github.com/riper/proverview).
And to re-calcul textarea height I count the number of line breaks multiply with line-height using :
it works correctly, maybe it’s simpler than creating an hidden clone textarea ?
@riper, an interesting approach but unfortunately it only works in certain situations (where there are line breaks). If I keep typing in a text-area then the text wraps but no line-breaks are created…
@James, there is a small glitch in this plug-in. If the last character of a sentence is a space then the cursor does not wrap down until a character other than a space is inserted. In any case, thanks for sharing this plug-in.
Great implementation. I added it to my site for the comment box because it’s a great little feature and easy to implement.
This is sweet. I’ve had a Post It note on my desk for a while with some things to develop. An auto re-sizer was one of them so now I don’t have to tackle that.
One quick question: is there a particular reason the re-sizer immediately adjusts the textarea on the first letter you enter then doesn’t again until a new line is necessary?
@CameronW, I believe that’s a feature/quirk of textareas in general, not related to this plugin…
@Jonathan Snook, Great! I’m glad you found it useful!
@Mark, The initial-resizing is a result of the default 20px ‘extra space’. You can change it in the the options. Thanks for your comment.
That’s a great plugin. Such a simple result yet so effective. Thanks!
Wows.
Such a simple utility with so many uses.
Simply amazing, wonder hoe you get ideas to create such stuff.
Will try to make something without jQuery framework. Not 100% same but feature will be same. Thats an assignment for myself this week. Please dont post anything about it if possible. If I find it very hard to make. Will ask for your help.
When I submit a form containing text areas that I’ve attached to autoResize, I get two ’streams’(copies) of content from each textarea being sent to the server for processing.
I think I’m using conventional naming protocols on my forms and text areas (the latter have an ID and a name)
Any idea of what I’m doing wrong/where to look for my error?
Thanks/Tom
Thanks for the comments!
@Swapnil Sarwe, Good luck porting it!
@Tom, that’s my fault I think. The plugin clones the textarea for testing purposes – and so there are two textareas with the same ‘name’ attribute. I just added a fix so if you try downloading the plugin again it should work…
This is really cool…I would recommend the additional option of providing a setTimeout() delay to the events that call the updateSize() method, something like:
This will make sure that it only resizes after 100ms of no typing, something I wish more than anything that Facebook would do with their auto-resizing fields. It eats up CPU time and occasionally even freezes the browser when every single keypress fires the event that does all that checking. You could have it disabled (the current behavior) if you set the delay to 0 or something. It would keep it from resizing immediately, but it would improve performance. That’s my 2 cents.
Wow. Great tutorial. It’s been bugging me for some time. Thanks for showing the way…
thanks! That is awesome.
Hey James, it seems as though long strings of text like a big URL just run off the textarea when the textarea should add horizontal scroll bars.
Thanks James, the updated script solved the problem – much appreciated.
Cheers/Tom
@Evan Byrne, Oops! The plugin applies an ‘overflow:hidden’ to the textarea; I thought it was necessary at first but it turns out it works the same without it. Thanks Evan! All fixed now…
- Anyone who is currently using the plugin please update to the newest version.
@Jeff, That’s an interesting idea. One problem: while someone is typing, the vertical scrollbar will keep re-appearing at intervals… as soon as you reach the end of a line it will appear, and then 100ms later it will disappear as the textarea expands. I see what you’re saying but the ‘updateSize’ function really isn’t a very intensive process. If you’re concerned about performance then imeplementing the timeout isn’t too tricky:
That’s a good point about the scrollbar. I guess I’d be less annoyed by a visual flicker than something that would hang the browser as I was typing, which is why I’d implement it. But I’m using Firefox 3 on Ubuntu 8.10 x64, which oddly seems to have pretty poor performance. It might not be anywhere near that slow on, say, the i386 arch, or Windows XP. Both of my readily accessible computers are running the same OS version, or I’d check right now. I might be trying to implement a JS-oriented fix for an OS-oriented problem, which is of course not the best idea.
Just wondering though, if you set CSS overflow-y to hidden, would that suppress the scrollbar flickering that you foresee?
@Jeff, Funnily enough, I had that exact same thought and just changed it so it now sets ‘overflow-y’ – also I thought it would be a good compromise considering the bug Evan just raised.
Another idea to improve performance would be to cut down on which events it runs on. Currently it runs on the ‘change’, ‘keyup’ and ‘keydown’ events. To be honest the ‘keydown’ event isn’t really needed and in desperate situations you could manage without ‘change’ as well… The reason I used all of them in the first place was so I could be sure to capture all possible methods of input, including pasting…
If you click in the textarea and hit tab, the textarea resizes regardless of if you typed anything or not. Not a big issue, but if you’re tabbing through a form it looks kind of awkward.
Otherwise, great plugin. There are others, yes, but you did a solid job and the animation is nice and smooth. I also like the extra options.
excellent plugin, James can do the same with iframes?
Just found a weird bug. Type something in the textarea then click somewhere else outside. Now, try to use the home, end, page up or page down keys. They dont work as expected anymore.
Tested using Firefox 3.0.7 on Windows XP.
Its working thank you! I’m using the plugin in a simple CMS and there is a problem.
The users type a large amount of text; textarea resize’s auto (= great!). They save the text …. and come back to edit.
Here’s the problem: the textarea is not resized on load (initially the textarea is filled with a large amount of text).
Same issue as Sjaak. Any suggestions on how to re-size the textarea to match the text after getting it from the dBase?
@Sjaak, @Rich, Try triggering the change event:
@James – Many thanks – works perfectly!
Really great , thanks
Hi James,
As I said in the comment section, I have tried to imitate autoResize. I have posted it on my website/blog: http://swapnilsarwe.phpnet.us/text-area-auto-xpander.html . It is completely based on your idea, only thing I did is gave a try without jQuery. Some of the code in the snippet is again based on code from your site/blog. My snippet don’t have any options right now, I’ll make it available by tomorrow.
Thanks a lot for hell lot of inspiration James. I owe you a lot.
Hi James,
Neat work, cheers.
I’ve found a small problem with the scripts: if you use CSS to set the width of the original textarea to be proportional (e.g. “width: 80%;”), then the cloned textarea will have a different width (since, as an absolute-position-element, its width will be 80% of the page, not 80% of the containing block).
I’ve had a quick glance at the code and it looks like you use jquery to retrieve the height of the original textarea, but not the width, hence the problem. I’ll try to patch this and get back to you…
Cheers,
D
Changes that seem to rectify the above problem:
[1] Remove the width attribute from the clone:
[2] Bind the pixel widths together:
That’ll probably cause some other bugs, of course…
Cheers,
D
As Mark pointed out, the initial resizing of the textarea due to the extra space is annoying. I understand that setting extra space to 0 fixes this ‘issue’ but having extra space is nice. Would be great if this could somehow be resolved.
Another point to bring up is that if my textarea already has a large amount of text (say, I’ve gone back to edit) the textarea won’t resize until I press another key. The easy fix to this is to add another event handler:
.bind(‘focus.dynSiz’, updateSize)
Great script, small and easy to implement. Cheers.
Hi,
Sorry but I think I’m stupid, I don’t understand how to use this wonderful script… Someone could show me an exemple with the HTML code et the javascript declarations?
Thanks a lot.
I think the initial resizing could be solved by replaceing:
with:
lastScrollTop = origHeightThis way, the first time the textarea is receiving input
lastScrollTop === scrollTop and the resizing will not be fired.
Optionally change:
to:
This changes the textarea back to the original height when you delete input, instead of original height+extraSpace.
Not sure though if it will cause some other problems…
Is there a way to auto-rezise DIV depending on the content inside the DIV tag? I likeyou’re plugin, but it seems to be confined to TextArea. Can this only be done on html Tags?
Thanks
Strange bug – in the example above when you type in the middle of the textarea and a resize occurs your cursor is placed at the end. But this doesn’t happen right here where I’m typing – what is the difference between the two implementations?
I cannot get this plugin to work. I really do not know what I am doing wrong. Here is the code I am using:
Type something in here, when you get close to the end the box will expand!
Hey James -> Thanks for this, I just dropped it in a project. Best, Matthew
Thank you James for the trigger(‘change’)!
Before it worked; but IE7 is not working anymore. The example above is working though.
Weird.
Here i copied the files: http://www.lukasmedia.nl/autoresize/index.html
IE7 -> not working.
FF -> working.
Please help!
Excellent plugin!
However, I found a bug when using different font sizes and font faces. The textarea does not scroll properly, when font size is different from default textarea font size. I did not look for the root cause of the bug, I just made a temporary solution.
In hidden textarea, line-height css-property gets value ‘13.5px’, even though the visible textarea does not have that css-property set.
Here is my quickfix:
I spent hours and hours and HOURS for this “bug” (i dont know if its bug or not) but here the solution for IE users.
My HTML – doctype looked like this:
!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
But in your/this example you use:
!DOCTYPE html
………………………………………………. i hope i just helped somebody
jQuery rocks! Thanks for sharing this little tool! Very useful for lot’s of my forms.
I have it working in all browsers but firefox on mac and win do not work.
The URL:
http://www.reditor.net/tortoise/tortoise.php
The CSS:
The XHTML:
The JS:
Can anyone help?
Im pulling my hair out trying to figure it!
Thanks for that plugin, mate!
Only one thing: will be a really great thing if, when the textarea is loaded with some content inside, and the content is bigger, the textarea is showed already with the right height.
So far, a function that check the textarea content and then resize it when the page is loaded will be fine.
I’ve tried to use $(‘textarea#yourID’).autoResize({/*options*/}).trigger(‘focus’); to make the autoresize trigger when the textarea is clicked, but wont work
sorrysorrysorry im a idiot
$(’textarea#yourID’).autoResize({/*options*/}).trigger(’change’);
works perfectly, why did i change it to
$(’textarea#yourID’).autoResize({/*options*/}).trigger(’focus’);
???
This plugin is great! How hard would it be to add:
a)Toggle function (So the textarea shrinks once the user has finished?
b)Each textarea within a table row to expand at once not just a single textarea?
Thanks again!
Hi guys, i have to report a bug (or meybe not?):
When the CSS of the textarea express the width in percentage, instead of pixels, IE increment the size of the textarea at every keyup.
How can i fix it? Or no way to keep the textarea’s in percentage with the plugin?
I had the plugin running at splitweet.com but I disabled it.
When the resize of the textarea is needed the cursor moves always to the end and that’s very annoying when you are editing text.
You can test by yourself the bug with the sample provided in this page. Type some text, move the cursor to the middle and continue typing. You’ll see that at the next resize you will be writing at the bottom.
Your script is very nice, but I have encountered a problem: the resizing function works fine, but the data typed inside the textarea aren’t transmitted, at Submit click!
I have tryed to attibute the same id to hidden clone textarea, but the trouble don’t solve…
What can you tell me about?
Ok, solved…
the trouble is in html code: I haven’t put a ‘name’ attribute to textarea, just the ‘id’ attribute…
;o)
Hi. Great plugin ! It helps a lot. I barely tried to do it myself in plain Javascript without Jquery but I couldn’t, because of this “rows & cols” management…
Anyway, this was the Thank you part.
But for my application, I needed a little adjustement of your plugin. I wanted to automatically extend textarea when needed but only extend, not diminish it. So I made some modifications to do that…
The new feature :
- Option “onlyExtend” : False, Classic use of your plugin / True, The box only extends but never diminish in size.
The code needed :
- Add the default setting :
onlyExtend : false
- Add a line between
“if (lastScrollTop === scrollTop) { return; }”
and
“lastScrollTop = scrollTop;” :
which is :
// Don’t diminish size if option “onlyExtend” is set
if(settings.onlyExtend && scrollTop < lastScrollTop) { return; }
With that, if the last scroll top value is higher than the current scroll top, the textarea will not adjust.
Hope you’ll find it useful.
–Didjor–
PS : Sorry for my english if there are some mistakes.
Well… I just spotted a bug…
I’m using the auto-resizable textarea in a div that can be resized manually. And if you extend manually the div, then you edit some text, the lastScrollTop value will be the height before the resize, so it will diminish the size.
A solution is to use for my particular test “$(this).height()” instead of “lastScrollTop”, which gives us :
if(settings.onlyExtend && scrollTop < $(this).height()) { return; }
–Didjor–
PS : Should I see somewhere how to put a code tag in my message ?
Great Plugin, thanks a lot.
Can you show me how you would use your example with the .live function?
Here is my sample code but it gives me errors:
$('textarea .blog_comment').live('autoResize', function(e,{
// On resize:
onResize : function() {
$(this).css({opacity:0.8});
},
// After resize:
animateCallback : function() {
$(this).css({opacity:1});
},
// Quite slow animation:
animateDuration : 300,
// More extra space:
extraSpace : 40
}){});;
Looks great, thanks.
One question, though –
Is there an elegant way to stop the plugin’s operation?
Something like
$(‘textarea#comment’).stopAutoResize();
thanks
@ Ido
I don’t know where this need might arise where you might need to stop the auto resize of the textarea. And even if you want to, there will be some condition where you might want to stop the resizing of the textarea and James has provided with the option of limit in this plugin, where you can specify the maximum height after which it will anyways stop the plugin.
Can you please be specific at which instant we might require such functionality or option.
If you place textareas in a hidden container and just display them when needed, the original height is set 0. So the textarea will be resized to a 1-row-size. As a quick fix, I’ve added the following code to the function updateSize()
Maybe there’s a better place for checking the zero-height?
Is there any way to stop writing when the texarea reaches the limit?
I think it would be a good solution to control the lenght of the content, depending on it’s height.
In any case, thanks for sharing this plug-in.
Please, can you help me ?
I really need to know how I can’t block writing, when the textarea reaches the limit?
thx for all
Hi!
Thank you very much for this excellent plugin.
Your coding skills are phenomenal, but unfortunately it’s a bit tough for a javascript layman like myself to fully understand all inner nuances.
I have an implementation question I’d like to put forward to the discussion, if possible.. as well as an update on a minor bug.
About extraSpace:
a) Is it possible to change the implementation so that extraspace is defined in lines rather than pixels?
b) With the extraSpace parameter, would it be possible to use up all the extra space before expanding the text area?
In other words, rather than expanding one line at a time, would it be possible to wait until the text reaches the bottom and then expand by the number of lines as dictated by extraSpace?
The bug:
You can verify with even the comment form on this page that expansion will always return the cursor to the end of the text.
@benno pointed this out earlier, but the bug is actually consistent across all implementations.
This is not noticeable when just typing from start to finish, but it’s very annoying to the point of unusability in production.
There is some code here: http://snipplr.com/view/5144/getset-cursor-in-html-textarea/
which may be useful, but it certainly does add some complexity to the whole codebase.
I will keep playing with the code but any help is also appreciated.
Best regards,
Here is another expanding plugin: http://plugins.jquery.com/node/1543
and this one: http://code.google.com/p/jquery-elastic/downloads/list
In IE8 the resizing happens when I leave the textarea. The example above works fine. Same doctype.
Could you please specify which license you’re releasing this code under? Very cool functionality, but can’t use it without knowing the terms of use. Thanks!
Hi James,
how to get the handles appear? After the js fires, there are two class=”handle” elements above and below the textarea. I cannot find where these come from. Please explain
Excellent plugin, one problem though… animateCallback doesn’t work for me in firefox… onResize works but I need a callback function to execute *after* the resize has happened. This is true even of the example code provided with only a simple alert() in the callbacks.
It’s great but it’s not working for predefined text – when the default textarea value is longer than textarea can show, plugin is not resizing textarea. It would be great if you’ll do something with that
The first thing I have to say is thanks for this plugin. It has helped me not have to try to program this myself and saved me a lot of time and work. But I have one problem I can’t seem to resolve. I added the .trigger(‘change’) to the end of the function to automatically resize textarea when a file is loaded. It works perfectly in firefox, but in IE7; it somewhat works. For some reason, the resize won’t completely resize the textarea to the correct height. Once I focus in on the textarea, it resizes again to the correct height. I don’t know what the problem is. Just starting looking at jquery
Very nice plugin !
However I have a very similar problem to JonathanK.
I’ve put this code to resize the textarea when it gains focus :
$(‘#my_textarea’).one(‘focus’, function(){
$(this).trigger(‘keydown’);
});
It works fine in FF and Safari, but not under IE8. When focused, the textarea (with content) resizes to an incorrect size, and then when a change/keyup/keydown event occurs, it resizes to the correct size… It seems that the clone.scrollTop() value is incorrect at the time of the focus event.
hey FM, I believe I fixed this by placing a clone.scrollTop(); at the beginning of the updateSize = function() { in autoresize.jquery.js. This seems to have helped. But for some weird reason, the fonts and size of resized textareas seem different somehow
JonathanK > Since I’ve chosen another solution (no displayed text in the textarea), I’ll try your solution if I go back to square one ! Thanks for the help !
Great work!
Quick question: Is there any particular reason Safari’s textarea resize handle disappears when using this plugin? I use those quite a bit myself and wouldn’t want to take away that option for Safari users.
Very nice!
Iv got this plugin working nicely but have one problem.
When I edit a record that has lots of text in a textarea, its not expanded (showing all the text) until you type inside the textarea for your plugin to do its thing.
Any ideas? (or know what im talking about :S)
Thanks!
Hi James,
great work and very useful!
However… I have found an odd bug (using FF 3.0.15 and 3.5.5 on windows), though and having real trouble figuring out what may be causing it!
If you have exactly 61 lines of text in an “autoresized” text area it works perfectly. (i.e. 60 lines with anything on them and CRLF at the end of the line and a 61st line with just text but no CRLF)
If you have 62 lines (or more) of text then it does not auto-resize. Do you (or anybody else) have any ideas about what might be causing this or how it could be fixed? It seems very odd!
This can be shown by creating 61 lines of text (just blank lines will do) and typing 61 on the last line. If you copy it all and paste into the autoresize box on this page it works fine.
If you then
(1) clear the box on this page, then
(2) add a 62nd line to your text document and
(3) copy/paste the 62 lines of text into the box on this page
You should see that the autoresize area stays at its original (small) size and does not expand. On IE8 the bug manifests slightly differently – very long text results in a text area that does not show all the content on screen, but yet has no scroll bars.
Any ideas or solutions would be great!
Christian
Also, +1 for Jeferson’s bug – I get the same problem.
Thanks for the great plugin!
Unfortunately I’ve found a hole for people who have web standards in mind; defining ROWS & COLS doesn’t affect HEIGHT of the TEXTAREA, but it does affect the SCROLLTOP() value, causing unexpected height changes on this plugin. ROWS & COLS attributes are are required on TEXTAREAs according to W3C standards, whereas the demo TEXTAREA here don’t specify these attributes.
For instance if ROWS=”100″ were to be declared with this plugin in use, the SCROLLTOP() value returns LINE-HEIGHT*100ROWS, even if there’s no input at all.
So to solve this problem, I added
$(this).removeAttr(‘rows’).removeAttr(‘cols’);
before
// Get rid of scrollbars and disable WebKit resizing:
var textarea = $(this).css({resize:’none’,'overflow-y’:'hidden’}),
to delete ROWS & COLS attributes if the plugin is loaded correctly.
This will make the markup pass the W3C standards by leaving out the ROWS & COLS attributes for clients who don’t have Javascript enabled, and at the same time stop the ROWS & COLS attributes from affecting the SCROLLTOP value if the plugin works correctly.
@Lex – I had the same problem but got around it by calling
$(this).keydown();
Immediately after calling:
$(this).autoResize();
In the calling javascript. This simulates a keypress in the box which triggers the auto-resize.
To clarify, I set up the auto-resize with the following code:
$(document).ready(function(){
$('.myclass textarea').each(function() {
$(this).autoResize();
$(this).keydown();
});
});
Christian