CodeinWP CodeinWP

Textarea Auto Resize

Textarea Auto ResizeOn a current project, I was trying to find a way to auto-resize a textarea according to some content that would be loaded in dynamically via Ajax. I didn’t know the height of the content and the textarea element doesn’t resize naturally like other HTML elements, so I needed to update the height of the element with JavaScript each time the content changed.

It seemed like a simple task. After doing a search to see what types of plugins and scripts were floating around to do this, the examples I found seemed a little overly complex. While most solutions seemed to incorporate some complex math calculations, I thought of a better way.

Using a Hidden Clone Element

A <div> element will naturally stretch to fit the height of its content (assuming no floats or absolutely positioned elements are involved). So to get the height of the textarea, I just need to do the following:

  • Grab the content loaded into the textarea
  • Create an invisible clone div
  • Give the clone the same width and typographical properties as the textarea
  • Place the content into the clone
  • Get the height of the clone
  • Apply the height of the clone to the height of the textarea

The Code for Textarea Auto Resize

One of the keys to this solution is the CSS. As mentioned, the invisible clone needs to have the same typographical properties as the textarea. Not only does this include stuff like font-size and font-family, but also the white-space and word-wrap properties of the clone need to be set to mimic what happens inside the textarea.

Take note that I’ve added overflow: hidden to the textarea, to prevent scrollbars from appearing. Normally this would not be a good thing to add to a textarea element, but because I’ll be resizing it with JavaScript, it’s fine. This CSS is added to the textarea with JavaScript, to ensure that if JavaScript is turned off, the textarea will scroll normally.

Here is the CSS I’ll be applying to the hidden clone element via JavaScript:

.hiddendiv {
  display: none;
  white-space: pre-wrap;
  word-wrap: break-word;
}

A quick break-down: First, I set it to display: none because I don’t want it visible to the user. I believe this should be fine for screen readers, because I don’t want it read out to them either.

I’ve also set the white-space property to a value of pre-wrap. This ensures that lines will wrap correctly, but everything else gets pre-formatted. The typographical properties are inherited, but I could also have adjusted those and then repeated them on the clone. In both examples, I’m giving the clone and the textarea a min-height so it will always start out at a standard, usable height.

Now for the JavaScript! I’ve commented the code in the block below as well as in the CodePen demo, so you can follow what’s happening:

// Targets all textareas with class "txta"
let textareas = document.querySelectorAll('.txta'),
    hiddenDiv = document.createElement('div'),
    content = null;

// Adds a class to all textareas
for (let j of textareas) {
  j.classList.add('txtstuff');
}

// Build the hidden div's attributes

// The line below is needed if you move the style lines to CSS
// hiddenDiv.classList.add('hiddendiv');

// Add the "txta" styles, which are common to both textarea and hiddendiv
// If you want, you can remove those from CSS and add them via JS
hiddenDiv.classList.add('txta');

// Add the styles for the hidden div
// These can be in the CSS, just remove these three lines and uncomment the CSS
hiddenDiv.style.display = 'none';
hiddenDiv.style.whiteSpace = 'pre-wrap';
hiddenDiv.style.wordWrap = 'break-word';

// Loop through all the textareas and add the event listener
for(let i of textareas) {
  (function(i) {
    // Note: Use 'keyup' instead of 'input'
    // if you want older IE support
    i.addEventListener('input', function() {
      
      // Append hiddendiv to parent of textarea, so the size is correct
      i.parentNode.appendChild(hiddenDiv);
      
      // Remove this if you want the user to be able to resize it in modern browsers
      i.style.resize = 'none';
      
      // This removes scrollbars
      i.style.overflow = 'hidden';

      // Every input/change, grab the content
      content = i.value;

      // Add the same content to the hidden div
      
      // This is for old IE
      content = content.replace(/\n/g, '<br>');
      
      // The <br ..> part is for old IE
      hiddenDiv.innerHTML = content + '<br style="line-height: 3px;">';

      // Briefly make the hidden div block but invisible
      // This is in order to read the height
      hiddenDiv.style.visibility = 'hidden';
      hiddenDiv.style.display = 'block';
      i.style.height = hiddenDiv.offsetHeight + 'px';

      // Make the hidden div display:none again
      hiddenDiv.style.visibility = 'visible';
      hiddenDiv.style.display = 'none';
    });
  })(i);
}

Note that the code works with multiple textarea elements on the same page, you just have to add the appropriate class in the HTML (in this case it’s txta).

I’m dynamically changing the height based on JavaScript’s input event, which is a good solution because it’s the most likely reason that you’ll want to auto-resize a textarea — user-entered data.

Do Old Browsers Recognize This Textarea Auto Resize Solution?

Almost nobody cares if this works in old versions of Internet Explorer, but the code does include a few lines that were originally there to fix a few issues in those browsers. The reason for this had to do with the poor way IE handles grabbing content using innerHTML.

The key line for old IE is this one:

// fixes the IE innerHTML problem
content = content.replace(/\n/g, '<br>');

But even after adding this line, there was still an issue: Long, unbroken strings of text wouldn’t affect the height of the textarea (which isn’t a big problem, really). A simple fix was adding word-wrap: break-word to the CSS for the clone element.

Bugs? Problems?

For a demo, you can view my CodePen below. Let me know if you find any problems with it. If you notice any problems, let me know in the comments.

See the Pen
Textarea Auto-Resize with JavaScript
by Louis Lazaris (@impressivewebs)
on CodePen.

117 Responses

  1. haliphax says:

    This would make for a fantastic jQuery plugin! Kudos.

    • Yeah, that was one of the ones that I found when initially researching this. The one bonus of James’s is that it actually works on input elements too, for expanding the width as you type.

      But I’m hesitant to recommend a plugin for this solution that’s 275 lines long. Maybe I’m missing something here, but my solution in this example is about 20 lines and if converted to a plugin could probably be around 30-40 max.

      There’s also an option on SitePoint:

      http://www.sitepoint.com/build-auto-expanding-textarea-1/

      Which is about 60 lines, commented — so much more reasonable I think.

      Edit:
      I initially said I couldn’t think of a reason to auto-expand an input but on second thought it would be useful to have an input element start out small then expand as you type (for long email addresses or whatever).

  2. Dwijayasblog says:

    Thank you this trick help me a lot.

  3. Chris Coyier says:

    I like the idea, clever. Just for the sake of another option, here’s one that is fairly short and library free that works really efficiently I think:

    http://www.alistapart.com/articles/expanding-text-areas-made-elegant/

    • Nice, I didn’t know about that one. Usually the ALA stuff doesn’t go under my radar. Obvious drawback for that one is the lack of support for IE6/7, but certainly a good option since old IE support is becoming less and less of an issue.

  4. Brian Nickel says:

    One problem I’ve noticed is that if you press “enter” to expand to a new line, the text area will be slightly scrolled, most likely because “<br>” at the end of a <div> doesn’t do anything. I overcame this with the following:

    hiddenDiv.html(content + ' ');

    If you don’t want the text to scroll briefly every time you reach a new line, you could do the following:

    hiddenDiv.html(content + ' <br> ');

  5. Nora Reed says:

    Nice Article. i am learning Web designing, i was just searching On “resizing” i found this article, which is really useful that Auto Resize, it will gonna save more time n Progress in this way! thanks for this very nice explanation n writing worth reading :)

  6. Jon says:

    This is seriously awesome! I can’t wait to use it on my blog.

  7. JNsites says:

    Great post, I enjoyed trying it out.

  8. Realy great article. Thank you, i try it :)

  9. kaeku says:

    Hey! I had to fix the same issue at work just last week. I solved it by getting the scroll-height of textarea and expanding it by the difference that was determined by subtracting the actual height from the scroll-height.

    It would look kind of like this:

    
    var el = $(this);
        
    setTimeout(function() {
            
        var height = $(el).height();
        var scrollHeight = $(el).prop('scrollHeight');
            
        $('#log').text('height: ' + height + ' scrollHeight: ' + scrollHeight);
            
        if (scrollHeight > height)
        {
            $(el).height(scrollHeight);
        }
    }, 1);
    

    After that, you just bind the function to the desired events

  10. MMiszy says:

    I’d rather use bind('input', .... instead of keyup as there more ways to enter text than just by keyboard ;)
    Moreover, instead of using div and replacing newlines with <br>, you could use <pre>.

    It would also be a great idea to set opacity of textarea to 0 and then apply some kind of syntax highlighting to the text-containing element (I’m thinking of binding highlighting to blur event).

    My code (from 1st Nov) can be found here: http://pastebin.com/j9LbTQb8

    • Just as an FYI:

      The “input” event only works in newer browsers, so although this seems like a good solution, it won’t work in IE6-8, so for now I’ll stick with “keyup”.

  11. Filip Bech-Larsen says:

    You could argue it makes sence to either add textarea{ resize: none; } to your css, or add something that turns the feature off when the user uses the manual resize of pulling the corner of the textarea. Maybe your script could be only to resize bigger, and not smaller? I, for one, like the illlusion of overview therefore often resizing textareas to be really large. If that cancelled after each key-up that would make me very tired :-D But great idea with the cloned element.

  12. Mc Benny says:

    A difficulty of your solution in case of several textareas or if you want to turn it to a generic system is the way you prepare your clone: by applying fixed styles. I encountered the problem a few years ago and I solved it by just getting the styles of the targetted textarea involved in presentation and putting them to the cloned element on the fly:

    $(tArea)
    .data({
    	'default':	$(this).val()
    	,'w':		$(this).width()
    	,'ttransform':	$(this).css('text-transform')
    	,'lheight':	$(this).css('line-height')
    	,'wspacing':	$(this).css('word-spacing')
    	,'ffamily':	$(this).css('font-family')
    	,'fsize':	$(this).css('font-size')
    	,'fweight':	$(this).css('font-weight')
    	,'lspacing':	$(this).css('letter-spacing')
    	,'wrap':	$(this).css('word-wrap')
    })
    ^t		.after('<div />')
    .next()
    	.css({
    		position:		'absolute'
    		,left:			'-9999em'
    		,width:			$(tArea).data('w')
    		,'text-transform':	$(tArea).data('ttransform')
    		,'line-height':		$(tArea).data('lheight')
    		,'word-spacing':	$(tArea).data('wspacing')
    		,'font-family':		$(tArea).data('ffamily')
    		,'font-size':		$(tArea).data('fsize')
    		,'font-weight':		$(tArea).data('fweight')
    		,'letter-spacing':	$(tArea).data('lspacing')
    		,'word-wrap':	$(tArea).data('wrap')
    	})
    	.text($(tArea).data('default'));
    
    

    By the way, you don’t need any padding on your cloned element.

    My function is about 70 lines of code and also accepts multiple classes to target the textareas, if any is interested.

    • You’re right about the padding on the clone. I’m in the process of updating the code so I’ll apply that style only to the parent. I’ll also look into grabbing the styles dynamically, but that would complicate the JS unnecessarily I think.

  13. ckozl says:

    Keep it real [simple] in this rap game:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset=utf-8 />
    <title>auto resize textbox</title>
    <style>
      textarea {
        resize:none;
        overflow:hidden;
        width:100%;
        height:100%;
        position:absolute;
        top:0;
        left:0;
      }
      div {
        position:relative;
        width:auto;
        height:auto;
        white-space: pre-wrap;
        word-wrap: break-word;
      }
      div, textarea {
        font-family:arial; 
        font-size:1em;
        padding:10px;
      }
    </style>
    </head>
    <body>
      <div><textarea></textarea></div>
      <script>
      (function() {
        var d = document,
            c = d.getElementsByTagName('div')[0],
            t = d.getElementsByTagName('textarea')[0],
            f = d.createTextNode('');
        
        c.appendChild(f);
        
        function updateSize() {
           f.nodeValue = t.value + '\n\n';
        }
        
        t.onkeypress = t.onkeyup = t.onchange = updateSize;
        
        updateSize();
      })();
    </script>
    </body>
    </html>
    

    link to jsbin: http://jsbin.com/adebol/1/edit

    Simpler, no jQuery, shorter easier javascript, quicker updating, no height calculation, reflow resize via css. You’re welcome ::bows:: -ck

    • Doesn’t work in IE6-8.

      You’re welcome. :)

      • ckozl says:

        LIES! works fine in ie8. ::shakes head at you for not telling the truth::

        as for ie6-7 support,
        change

        white-space: pre-wrap;
        to
        white-space: pre;
        using an ie < 7 specific hack…

        like so:

        
        <!--[if lte IE 7]>
        <style>
        div {
            white-space: pre;
          }
        </style>
        <![endif]-->
        

        jsbin: http://jsbin.com/uvebag/1/edit

        …so i’ll say it again. You’re welcome!
        And due to the invalidity of your prior statements, I expect a written apology… preferably with some mother effin smiley face stickers… ;-)
        -ck

        • That’s strange, because I was looking at it in “edit” mode on JSBin, and it doesn’t work in IE8 there, but it does work in preview mode.

          That is strange, as it should work the same, since it’s just an iframe.

          So, you’re right, sorry for the hasty reply, but I was looking at the code view in Chrome then copied and pasted the URL into IE8. Thanks.

        • I have to admit, after examining this code a little closer, this really is a great solution. The only minuscule drawback is the extra div, but you could easily add that via JavaScript instead, and then the HTML would be clean. But I’m fine with it either way.

          Kudos on this, great thinking — and great that you can take advantage of as much CSS as possible without needing a JS library or much JS at all.

          • ckozl says:

            Thanks for the kind words. It’s only a slight evolution of your concept, at its core its still using the “use a DIV to measure text size”. And I agree if I were packaging this as a plugin or in a library the DIV would get added dynamically on the target textarea/input via
            $('textarea#foo').autoResize({ vertical: true, horizontal 400 });
            or something to that effect, and you would obviously use targeted css class names… I just wanted represent the concept as simply as possible. Hats off for doing the leg work on the original concept. -ck

    • keekimaru says:

      Thank you very much. IT Work. ^^

  14. AntoxaGray says:

    This should become default functionality in browsers. I get sick of 3-line textareas.

  15. Samuel says:

    Thanks for your article, i’m beginning in CSS and it looks like its a real challenge to get good at it. Anyway i want to so i’ll bookmark your site! ;)

  16. Tim says:

    Awesome work, love keeping it simple!

  17. I was developing and needed a quick solution that I’ll optimize later.

    Call this function on whatever you want.
    id can be class tag or id

    
    function adjustTextarea(id){
    	var txt = $(id),
    	hiddenDiv = $(document.createElement('div')),
    	content = null;
    
    	txt.addClass('noscroll');
    	hiddenDiv.addClass('hiddendiv');
    
    	$('body').append(hiddenDiv);
    
        content = txt.val();
        content = content.replace(/\n/g, '');
        hiddenDiv.html(content);
        txt.css('height', hiddenDiv.height());
    
    	txt.bind('keyup', function() {
    
    	    content = txt.val();
    	    content = content.replace(/\n/g, '');
    	    hiddenDiv.html(content);
    
    	    txt.css('height', hiddenDiv.height());
    	});
    }
    adjustTextarea('textarea');
    

    I copied this exact snippet into my console and made your textarea adjust lol.

  18. Ben Demboski says:

    I just wrote a jQuery plugin for auto-sizing textareas using this approach. I call it Yet Another Auto Resizer (YAAR), and you can find it here: https://github.com/bendemboski/jquery-yaar. I’d love to hear what folks think of it.

    • Hey, Ben. Good idea! I should really do this myself when I get some time.

      I’m trying to get your script to work, but I can’t. Does it require certain CSS set on the textarea? Here’s my fiddle:

      http://jsfiddle.net/zSHYh/

      I must be doing something wrong… ? I also don’t see a live demo linked on your GitHub repo. Maybe throw a fiddle link on there so people can see a working version.

      Thanks!

  19. mike says:

    excellent

  20. Thanks mate, this helped. All I noticed is that errors occur is you do not clone the css styling applied on the textarea exactly same on the div. It did not work pretty great at the first go albeit when I applied the same padding, borders etc – worked!

  21. Laravel says:

    Expanding textareas, awesome.

  22. I added little fix enter. When user hit enter then there was no go to new line. See improved version: http://jsfiddle.net/fGNNT/872/

    • I don’t see a problem with hitting enter on the original version. Can you explain what it is you’re trying to fix with that? Maybe I don’t understand..? What browser are you using?

      • Try to typing something and then hit enter, enter, enter until you will go at very bottom of textarea. Just before the end of textarea. Then hit anter and you will see cursor on the next line, but textarea is not stretched until you’ll not hit any key.

        Tested on IE9 (9.0.8112.16421) and Firefox 13.0.1. Probably the same thing is on other browsers, but not tested.

        • Hmmm. I don’t see a huge difference. The major difference I see is that the first line of text (before hitting enter) gets pushed slightly up, getting cut off momentarily.

          But it seems like a minor thing. Anyhow, I’ll take a closer look and maybe I’ll update it with your fix, pending some further testing. Thanks.

  23. Dina says:

    Hello there!

    I am new to JS and CSS, and I need to use your script in a project I am currently working on. Essentially, it achieves what I need, however, I need to apply it on ALL the textareas that are in the page and not a single one only.

    I read your hint: “This code assumes we’re targeting a single textarea element on the page. If you need this to affect more than one element, then just change the first line inside the function that defines the element we’re working with.”

    and hence tried to change the selector from id-wise to class-wise as follows:
    var txt = $(‘.comments’)

    and tagged all the textareas with the “comments” class, but it works on the first textarea element it encounters only. Perhaps I am doing something wrong? Help please!

    • Dina, you’re right. Looks like I didn’t think it through properly.

      Here’s a corrected version, with multiple textareas:

      http://jsfiddle.net/jRpNM/

      I will eventually updated the post to fix this bug. Thanks for pointing this out!

      • Dina says:

        Thank you Louis, it works perfectly!
        It’s great that you are still keen to improve your script, and its my pleasure to report more bugs :D

        I encountered an initialization problem. To be specific, if the Texarea already contains some text when the document is loaded and if this text exceeds the TA’s bounds, the TA does not expand. Of course this is because the script is bound to the keyup event only and so far when loading, no keys are released.

        How the script works now makes sense if the assumption is that users are only allowed to type “after” the document has been loaded and the script bound to the component, but not allowed to have a “pre-populated” text area.

        At the moment I solve this by simply repeating what you do in the bind function but without binding anything, just doing the copy into div, get height, copy back the height thing. I feel though its not the cleanest approach :D

        Do you have an idea how to do it better and cleaner? can one bind the same function to the same variable but with two different events? if yes, what event-type would correspond to “onload”? (I know google is my friend, I already googled and tried out some stuff, but unfortunately I am still too new to this to spot why it doesnt work).

        Thanks again!
        Dina

        • Good question, Dina! This is good stuff, because it’s helping me to refine the script, as I’m planning to eventually code it as a real jQuery plugin.

          To do what you want with previously existing text, you could do it a couple of ways, but I think the shortest way is to force the keyup event using “trigger”. Here it is:

          http://jsfiddle.net/jRpNM/1/

          Notice the fields now have different amounts of default text and they resize accordingly.

          Oh, and that reminds me, another thing you should do is change the “bind” handler to “on”, the latter of which is now deprecated in the latest jQuery. So the updated code with both fixes looks like this:

          http://jsfiddle.net/jRpNM/2/

          • Dina says:

            Perfect!

            I am actually using your script in a totally different context. I’m trying to style a textarea’s scrollbar by hiding it, auto-expanding the TA as a user types and wrapping it up in a div where its much easier to style this div’s scrollbar. Now the the div is in control of panning through its child element, the TA.

            Still some problems to go, but at least now they are less :)
            If I find other bugs, I’ll let you know. Thanks!

            Dina

  24. fatih says:

    the double backslash

    content = content.replace(/\\n/g, '');
    • You’re right, I’ll fix that. Although it still works either way, apparently regexp statements using “/n” are supposed to escape the backslash and thus use double backslash. Thanks.

    • Changed my mind. For some reason, this breaks it in IE8. I don’t know enough about regular expressions but I’ll have to stick with single slash for now.

  25. I just came across this other solution, which you can see here:

    http://jsbin.com/idemad/2/edit

    The code is very small, and from what I can see, it works everywhere, including IE7/8. The only problem in IE seems to be the fact that the textarea always shrinks down to a single line when you click out of it after deleting anything you’ve typed.

    But if you don’t care about IE<9 then this might be a good choice. Credit for this goes to "user1432124" who gave this answer on a StackOverflow thread about auto-resizing textarea elements.

    • Wes says:

      I found one major benefit to this code – less lag. If typing quickly, this solution works very well. I’ve found that Louis’ code can lag 20 or more characters.

      • Hmm… that’s odd. I don’t have that problem at all.

        But even if that’s true, it’s somewhat irrelevant, because the only time the element auto-expands is when you create a new line (either by reaching the end and wrapping, or else hitting “enter”), so it really shouldn’t lag.

        Can you create a screencast showing this happening in comparison to the other code? You can use screenr.com for a quick easy screencast to share. Thanks.

        • Wes says:

          Can’t do a screencast since it doesn’t show when fingers stop hitting the keys. I must admit that this only happens when a VERY fast typist (85+wpm transcriptionist) gets going and it quickly catches up when input stops. You can simulate by just hitting keys as fast as you can (be sure include a spcae) and not worry about it being real words.

  26. Wes says:

    Any downsides to using scrollHeight? Seems to work for me. This will maintain the minimum of 50 and expand/contract as needed:

    
    txt.bind('keyup', function() {
           var sh = this.scrollHeight;
           this.style.height = sh < 50 ? "50px" : sh+"px";
    });
    
    • According to this page:

      https://developer.mozilla.org/en-US/docs/DOM/element.scrollHeight

      scrollHeight is supported in IE8+, so if someone needs support below that, then it might not work.

      But… I tested it in IE8 in IE7 mode, and it seems to work exactly the same way as IE8. I also tested in IE7 on IETester, and it works the same way. So I’m not sure what to think.

      So my guess is, yeah, this seems to be the better script simply because it’s so small and does pretty much the exact same thing as mine and any of the other really long scripts available online for this.

    • Ah… this page explains:

      http://help.dottoro.com/ljbixkkn.php

      It says:

      In Internet Explorer earlier than version 8, [scrollHeight] retrieves the height in physical pixel size, while from version 8, it returns the height in logical pixel size… The height is calculated in the default pixel size in Internet Explorer before version 8 even if the current pixel size in the document is different. From Internet Explorer 8 … the height is calculated in the current pixel size.

      So I think it’s safe to use, because that seems to be a not-too-significant edge case problem at most.

      • Wes says:

        I’ve noticed that it works fine while adding – but removing text seems to act weird – only seems remove about a pixel per event.

  27. Wes says:

    I am using a triggered keyup event (as referenced earlier in this great blog) and it works fine except for an area that is not shown when the page loads – it is located in collapsed tab. Any ideas for getting that to pre-expand?

    Thanks also for your incredible response time. I am amazed.

    • Wes says:

      Sorry, I jumped the gun with this request – I thought it would be difficult to solve but the jquery tabs docs (http://jqueryui.com/demos/tabs/#event-show) had a solution – I trigger the keyup when the tab is shown via the tabs show event. It fires for all selected elements, even those on the tabs just hidden, but that shouldn’t be much of a problem.

      
      $( "#tabs" ).tabs(
      {
        show: function(event, ui) { $(".expand").trigger('keyup'); }
      }); 
      
  28. Andrew says:

    This is the code turned into a jQuery plugin: http://jsfiddle.net/andrewtomici/4mW2S/
    It’s easier to use it this way.

    Save the JavaScript code from the jsfiddle in a js file.

    Example code:
    $(‘.comments’).autoresize();

  29. bacr says:

    hi, I would like to take the width of a parent element, so I did some modifications, but for any reason this is working in IE8 but is not working in IE7(it expands horizontally). Do you have an idea why is this happening ?

    
    (function ($) {
       $.fn.extend({
          autoresize: function () {
             return this.each(function () {
                hiddenDiv = $(document.createElement('div'));
                content = null;
                $(this).addClass('txtstuff');
                hiddenDiv.addClass('hiddendiv common');
                $('body').append(hiddenDiv);
                $(this).on('keyup', function () {
                   myParent = $(this).parent('td');
                   content = $(this).val();
                   content = content.replace(/\n/g, '');
                   hiddenDiv.html(content + "");
                   hiddenDiv.css('width', myParent.width());
                   $(this).css('height', hiddenDiv.height());
              });
         });
        }
      });
    })(jQuery);
    

    thanks.

    • Can you post this on a JS Fiddle, so it’s working in IE8, and then I can debug it to see what’s wrong in IE7? Thanks.

      • bacr says:

        Sure no problem. http://jsfiddle.net/KrvnK/1/
        To tell you the true, I have a table and inside the table I have asp textbox, so the parent of this textbox is a td element. The issue is that when I enter data in the textbox at some point the textbox begin to expand horizontally. This happen in IE7, IE8 works ok.

        • bacr says:

          Sorry, you should you change the framework to JQuery to get it work. Thanks.

        • I don’t see the problem that you’re referring to. I tested in IE8 natively, and that’s fine.

          Then I tested in IE8 in “IE7 mode” and that works the same way. I also used IETester to test in IE7, and I got the same result, it works exactly the same as in IE8.

          What kind of IE7 are you testing in? I can’t test IE7 natively. Are you using some standalone thing?

          Can you record a screencast using screenr.com, showing what is happening in IE8 compared to IE7? That would be helpful, so I can see what you’re talking about. Thanks.

  30. Stasonix says:

    A one little problem, what if I turned off javascript?

    • Then it just works like a regular textarea, no expanding. That shouldn’t be a problem in most cases. You could allow the textarea’s natural size to be set via CSS (for no js) then change it with JS, and allow auto-expanding. You could also use Modernizr and use the no-js class.

  31. Kvet says:

    Why you don`t use

    $(...).bind('input propertychange', ...)

    ?

    It works great for me!

  32. Tobias says:

    too complicated.

    $(‘.editnote’).live(‘keyup’, function(e) {
    var height = $(this).height();
    var scrollheight = $(this).scrollTop();

    if((scrollheight + height) > height) {
    $(this).height(height + 16 + ‘px’);
    }

    });

  33. mayumi says:

    Thanks you!!

  34. tugelsikile says:

    thanks, been looking for this :D

  35. HGN says:

    Thank you Louis, I finally found something useful! The other one in the web scrapped from Facebook has conflicts with other versions of jquery, yours is perfect!

  36. Made it work on all textareas that have .auto-resize on them.

    http://jsfiddle.net/fGNNT/1789/

  37. Rong says:

    This is cool, but it misses all situations:
    (1) The user could type texts into the textarea with keyboard.
    (2) The user could paste texts into the textarea with shortcut for keyboard.
    (3) The user could paste texts into the textarea with mouse.

    Unfortunately, the current code does not cover all three situations well.

    • As far as I can see, only the third one in that list doesn’t work, and I’m not sure why not. It seems like it’s very rare that a user would paste with their mouse only, but I suppose it’s an edge case that could be handled.

      I’ll make a note of it and see if I can improve it. Thanks.

    • Here you go, problem solved:

      http://jsfiddle.net/ImpressiveWebs/fGNNT/1885/

      Now all three should work correctly. It was just a matter of changing the event from “keyup” to “input”. I don’t know if this works in all browsers, however. I only tested latest versions.

      • chenar says:

        it not work in ie10

      • arjun menon says:

        it would be also good to add a scrollbar after reaching a certain height. otherwise, it would just keep on growing like king kong

        • arjun menon says:

          also, why isnt the rows value not working

        • Well, that is the point, that it grows as much as is typed. If you want a scrollbar, then there’s no point using this plugin, just set a height in the CSS. :)

          And as for rows/cols: In the main demo I can see “rows” working fine until you start typing, then the box goes back to the size based on number of lines. Cols doesn’t work because the CSS overrides it with a width. Just remove that and it should work.

          But I don’t think you need a “rows” value, again, for the same reason mentioned before, because the rows are dependent on the lines typed. If you want a min-height that it starts out as, then just set that in the CSS.

  38. sudha says:

    its not working when i use the same code in my jsp. its not autoresizing the text box. its hiding first linesof text when i type more lines in my textbox. its not autoresizing.can any one help me.

    body {
    margin: 20px;
    }

    p {
    margin-bottom: 14px;
    }

    textarea {
    color: #444;
    padding: 5px;
    }

    .txtstuff {
    resize: none; /* remove this if you want the user to be able to resize it in modern browsers */
    overflow: hidden;
    }

    .hiddendiv {
    display: none;
    white-space: pre-wrap;
    word-wrap: break-word;
    overflow-wrap: break-word; /* future version of deprecated ‘word-wrap’ */
    }

    /* the styles for ‘commmon’ are applied to both the textarea and the hidden clone */
    /* these must be the same for both */
    .common {
    width: 500px;
    min-height: 50px;
    font-family: Arial, sans-serif;
    font-size: 13px;
    overflow: hidden;
    }

    .lbr {
    line-height: 3px;
    }

    /*global document:false, $:false */
    var txt = $(‘#comments’),
    hiddenDiv = $(document.createElement(‘div’)),
    content = null;

    txt.addClass(‘txtstuff’);
    hiddenDiv.addClass(‘hiddendiv common’);

    $(‘body’).append(hiddenDiv);

    txt.on(‘keyup’, function () {

    content = $(this).val();

    content = content.replace(/\n/g, ”);
    hiddenDiv.html(content + ”);

    $(this).css(‘height’, hiddenDiv.height());

    });

    • You’re going to have to provide a live link that I can look at, then I can see what the problem is. The code alone will not help much, especially if you just copied it from my post.

  39. + 1 to jquery autoResize plugin … just works

  40. Anonymous says:

    Thanks for the post!

    Change these 2 lines:

    
    content = content.replace(/\n/g, '');  
    hiddenDiv.html(content + '');
    

    to this:

    
    content = content.replace(/\n/g, ' <br> ');
    hiddenDiv.html(content + ' <br> ');
    

    And the text stops jumping on entering a new line and the resizing is smooth.

  41. Rizaldi says:

    nice trick… Thanks for sharing…

  42. Justin says:

    Thanks nice code!

    Only when I try to print my page it shows the textarea content of the last active field twice.
    Any ideas how to prevent this?

  43. Justin says:

    Hi Louis,

    When I use textarea width:50% (responsive site) and I copy-paste a large text inside the textarea, the text does not show completely (it scrolls).

    http://jsfiddle.net/fGNNT/2417/

    Maybe you can help me solve this one?

    • In the CSS you’ll see this:

      
      .lbr {
          line-height: 3px;
      }
      

      Change it to a unitless line-height, something like:

      
      .lbr {
          line-height: 2.2;
      }
      

      That should correct it. You might have to adjust it slightly for your particular case. You could use pixels too, and just adjust it to whatever you want, but it’s always better to use unitless line height values. This is an older script so I didn’t use that back then.

      Hope that helps. Took me a few minutes to figure it out. :)

  44. Justin says:

    I played with the line-height and small and big copy paste text, but could not get it to work in every situation.
    http://jsfiddle.net/fGNNT/2427/

    Think I will set a fixed width for every device, that causes no problems.

    Thanks

    • It looks ok to me at different widths. I’m on Chrome.

      You could also try adding box-sizing: border-box to the .common element, to see if that helps slightly, assuming your CSS doesn’t use it universally already.

      • Justin says:

        At the moment I am only testing with a clean code.

        1) Go to: http://jsfiddle.net/fGNNT/2428/
        2) Copy paste in textarea the following text:
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ligula nulla, tristique nec pretium eget, aliquet sed magna. Integer ultricies ipsum ultrices tellus porta tincidunt. Curabitur a laoreet dolor, quis porta sapien. Morbi augue nisi, euismod et porta sit amet, euismod in metus. Integer hendrerit libero sed purus sagittis, eget sagittis odio posuere. Nunc velit metus, interdum quis leo vel, posuere laoreet ligula. Cras quis tempor ligula, ac tempus justo. Phasellus et nisl ac lorem pretium vulputate. Praesent at mollis justo. Sed sagittis felis sit amet purus posuere, eget mattis libero tristique. Vestibulum id faucibus risus. Vivamus libero mi, sollicitudin at dui at, tincidunt pretium lorem. Nullam euismod sem eu arcu aliquam sollicitudin bibendum venenatis dui.
        3) Not all text is shown (tested in chrome and firefox).

        Funny thing is, once I resize the browser window I eventually see all text. But never initially.

        • Yeah, I think you’re right. The way it is now, there doesn’t seem to be a way to get it working for each window size. Oddly, if you resize the window, then go back to what it was, it fixes it.

          So yeah, right now, the best solution seems to be to have different widths for different window sizes.

  45. Vin Byori says:

    This is really unique and efficient. Just the solution i was looking for; we have two plugins running in our site and strangely only the first one loaded would work which is an ajax pagination plugin. The second plugin is a textarea modifier(makes it auto resize). With this i can have both features up and running! Thank you very much =D

  46. Alexandre Coelho says:

    Thank tried a lot to find it without a doubt the best solution . ( Sorry for the google translation of the kkk ).

  47. Mart says:

    Sharing the best answer,
    no jQuery, no need to think, just copy and paste 3 lines : a link :

    http://www.cryer.co.uk/resources/javascript/script21_auto_grow_text_box.htm

  48. here is a bit i have added to this code check it out
    :)
    http://jsfiddle.net/r53sofqe/
    now cut n past handlers are in effect as well
    joshuabissot@wizardsofwords.org

  49. Anton says:

    Oh, come on guys! It is much simpler!


    jQuery('#textarea').on('keyup',function(){
    jQuery(this).css('height',this.scrollHeight + 'px');
    });

  50. Devend says:

    Thank you for this simple idea!

  51. marc says:

    Doesn’t work on your site in actual FF DEV Edition.
    Only works in fiddle :)
    But great idea, will take a closer look

    • Thanks, that was being caused by the fact that I switched my site over to HTTPS. That page was loading jQuery from HTTP which isn’t allowed by default on HTTPS. I’ve fixed it, so it should work now.

  52. kas says:

    Thank you so much!
    Using width: 100% I added the following line to your javascript function, setting the width of div to the width of the textArea element prior to resizing the height of the textArea:
    divHidden.style.width = element.getBoundingClientRect().width + ‘px’;
    I apologize if someone has already stated this.

  53. Thomas Deutsch says:

    I also worked with this, and make some tweaks.
    http://jsfiddle.net/fGNNT/3171/

    • Thomas Deutsch says:

      Changes:
      – added a ::after content to the hidden div
      – event is now an input event
      – added the same padding as the textarea to the hidden div
      – removed the new line addition to the hidden div in the event handler.

  54. mike says:

    I’ve created the following version in case you have more than one textarea but with different styling

    /*global document:false, $:false */
    var txt = $('#comments'),
        hiddenDiv = $(document.createElement('div')),
        content = null;
    
    txt.addClass('txtstuff');
    hiddenDiv.addClass('hiddendiv');
    $('body').append(hiddenDiv);
    
    txt.on('input', function () {    
     hiddenDiv.css('font-family',$(this).css('font-family')).
        width($(this).width()).
        css('line-height',$(this).css('line-height')).
        css('font-size',$(this).css('font-size')).
        css('padding',$(this).css('padding')).
        html($(this).val());
     $(this).css('height', hiddenDiv.height());
    });
    
  55. Santhosh DK says:

    Hi,

    Does anyone know how to achive the same in vaadin 7 frameworks?

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field and deep URLs are not allowed in the "Website" field. If you use keywords or deep URLs, your comment or URL will be removed. No foul language, please. Thank you for cooperating.

Markdown in use! Use `backticks` for inline code snippets and triple backticks at start and end for code blocks. You can also indent a code block four spaces. And no need to escape HTML, just type it correctly but make sure it's inside code delimeters (backticks or triple backticks).