62

I understand there has been a lot of discussion on this but I have yet to find a solution to fix my needs. Basically I need to autogrow a text area not when you type but on load. I am pulling in content from a database and dependant on the user's settings an overlay is produced over the text area, but upon doing this the text areas are not scrollable therefore I need to autosize these to show all the text.

I have tried scrollHeight but this is not working great as there are multiple text boxes on the screen

Thanks

CR41G14
  • 5,464
  • 5
  • 43
  • 64

7 Answers7

122

Try this

$("textarea").height( $("textarea")[0].scrollHeight );

DEMO


UPDATE

As a hack to make it work in older IE-s just add a really short delay before executing it

window.setTimeout( function() {
    $("textarea").height( $("textarea")[0].scrollHeight );
}, 1);​

DEMO

UPDATE FOR MULTIPLE TEXTAREAS

$("textarea").each(function(textarea) {
    $(this).height( $(this)[0].scrollHeight );
});
ashkufaraz
  • 5,179
  • 6
  • 51
  • 82
Zoltan Toth
  • 46,981
  • 12
  • 120
  • 134
  • This does not work in IE8 when you have multiple text areas. I have a large page with some heavy reliance on js for validation. Is there something in IE8 which may affect this? – CR41G14 Oct 26 '12 at 11:26
  • This will also set the height of all text areas to the size of the first textarea in the array of html elements returned by jQuery. – Bruno Oct 26 '12 at 16:23
  • 4
    @bruno This is an example what to use to solve the **real** issue. I'm pretty sure the OP won't have trouble to adapt the working example to his real situation which might include one or several textareas - the whole difference will be just a simple `each()` – Zoltan Toth Oct 26 '12 at 16:58
  • 1
    This doesn't work on multiple textareas on the page - use Tormod Haugene's code instead - works GREAT – Scott Oct 29 '15 at 14:58
  • 1
    This is the kind of stuff ***why I love this place*** :D Ask Google the right question, as someone did in SO, and, presto, your snippet needs fulfilled! – brasofilo Jan 26 '16 at 23:23
  • @ZoltanToth Simply Excellent. – Nikhil sHETH Apr 04 '17 at 08:07
  • Seems like this only makes the textarea larger. If the text contained is smaller than the height of the textarea it does not appear to shrink it. – Jake Wilson Aug 29 '17 at 17:58
  • @JakeWilson You are right. The `scrollHeight` of textarea will be at least as high as the textarea itself, so when the textarea is taller than the content nothing will happen. The solution does not resize the textarea to fit _all_ content - short or tall - rather it applies to context of the question and fixes the issue of large text in a small textarea. – Zoltan Toth Aug 29 '17 at 19:11
  • This seems to increase the height of the textarea indefinitely if you run it multiple times. But the solution is simple just remove the style height before you get scrollHeight. $('this').css('height', ''); It might help someone ... Isn't $this a typo and you meant $(this)? – Geza Turi Oct 13 '17 at 07:59
  • if you delete text...the textarea doent shrink – joe Mar 31 '18 at 18:19
  • @joe sure it doesn't - its' height was set during the onload event. If you want that functionality, then you have to implement it, e.g. set `height: auto` when an `onChange` event happens – Zoltan Toth Apr 01 '18 at 16:56
42

This worked for me; it loops through all "textarea" elements on page Ready, and set their height.

$(function () {
    $("textarea").each(function () {
        this.style.height = (this.scrollHeight+10)+'px';
    });
});

You can also combine it with an auto-expand function, to make it fully dynamic while writing as well:

function autoresize(textarea) {
    textarea.style.height = '0px';     //Reset height, so that it not only grows but also shrinks
    textarea.style.height = (textarea.scrollHeight+10) + 'px';    //Set new height
}

and call that from an "keyup" event or through jQuery:

$('.autosize').keyup(function () {
    autoresize(this);
});

Note how I am adding 10px to the scroll height: here you can adjust the amount of space you would like the bottom of the text area to give the user.

Hope that helps someone. :)

Edit: Changed answer according to @Mariannes comment.

Tormod Haugene
  • 3,538
  • 2
  • 29
  • 47
  • 2
    Many thanks, this worked for me with a little modification. I set the 0px to 2em, and I'm not sure why you have "-10", I changed to "+10" so there's always a little whitespace below and it doesn't feel cramped. – Marianne Oct 19 '13 at 13:09
  • 1
    Best answer for a well rounded and universal solution. Adjust -10 to desired padding of your textareas. – DreamTeK Jul 29 '14 at 14:46
13

you can use this. It works for me.

$('#content').on('change keyup keydown paste cut', 'textarea', function () {
        $(this).height(0).height(this.scrollHeight);
    }).find('textarea').change();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="content">
  <textarea>How about it</textarea><br />
  <textarea>111111
222222
333333
444444
555555
666666</textarea>
</div>
reza.cse08
  • 5,938
  • 48
  • 39
5

You mentioned there are multiple textboxes. This code will set the height of each textarea according to its own contents.

$(document).ready( function( ) {

    $("textarea").each( function( i, el ) {
        $(el).height( el.scrollHeight );
    ​});

});

Fiddle here

Bruno
  • 5,772
  • 1
  • 26
  • 43
  • This does not work in IE8 when you have multiple text areas. I have a large page with some heavy reliance on js for validation. Is there something in IE8 which may affect this? – CR41G14 Oct 26 '12 at 11:32
  • 4
    I am not sure why the downvote. IE8 compatibility was not mentioned in the question. – Bruno Oct 26 '12 at 16:35
3

Alternatively, you could use an editable div in HTML 5.

Reference : http://www.w3.org/TR/2011/WD-html5-20110525/editing.html#contenteditable

Florian F.
  • 4,700
  • 26
  • 50
2

This is an workaround.. and maybe an alternative solution:

 $('textarea').each(function(){
    var height = $('<div style="display:none; white-space:pre" id="my-hidden-div"></div>')
                 .html($(this).val())
                 .appendTo('body')
                 .height();     
   $(this).css('height',height + 'px');
   $('#my-hidden-div').remove();

});

You can see a demo here http://jsfiddle.net/gZ2cC/

Mihai Matei
  • 24,166
  • 5
  • 32
  • 50
0

The solution of Tormod Haugene worked for me.

But my textareas where in an accordion and apparently it only worked if the textarea was visible on page load. The accordion items are triggered by clicking on elements with the class "title".

So I adapted the code Tormod Haugene to work inside accordion contents, that are set to display: none on page load.

Maybe this is useful for someone else in this situation:

jQuery(document).on('click', '.title', function () {
    jQuery("textarea").each(function () {
        this.style.height = (this.scrollHeight+10)+'px';
    });
});
rank
  • 2,361
  • 2
  • 10
  • 20