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 false no animation will take place, the height will immediately change when necessary. By default it's set to true.
  • 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 onResize callback.
  • 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