A notch above a monkey » Auto-grow TEXTAREA

Auto-grow TEXTAREA

Update 6.8.2009: This post is old and somewhat obsolete, but has been kept alive by commentators. Hence I posted an updated version of the script in comments.

Fry recently mentioned a TEXTAREA improvement he found. As you type your text in the box, it grows in length as needed to avoid having to deal with scroll bars.

I liked the idea and went to create my own version. Making it work in Internet Explorer and Firefox was literally a matter of seconds. All you really need to do is compare elements clientHeight with its scrollHeight on key presses and increment rows attribute when former is smaller than later.

But supporting Opera and Safari has proven to be an insurmountable task for now. They simply don’t seem to update any property that could reliably be used for measuring the height of the text (but would love to be proven wrong).

You can try a demo, which also doubles as a test environment for reading interesting attributes on the fly (updates are done with mouse over input box).

Random bits of observation:

  • scrollHeight is always bigger than clientHeight in Opera. Hence the need to ignore it using its unique fingerprint.
  • I didn’t try to work out the length of the text by trying to count the number of lines (using \n) and the length of each of them. Proportional fonts prevent any such reasonable guess.
  • I didn’t try to limit the growth of the box to the boundaries of the screen. I find page scroll bars the least annoying when scroll bars can’t be avoided. It’s a personal choice though.

Comments (21)

  1. Thks!!!. I want an interface like Netvibes…this article was the solution for the Notes section…

    Comment by Optimcol #
  2. I myself is developing one of this also, however,the scroll bar will still show on pressing enter key, therefore, it’s better increase the height value when enter key is down(e.keyCode == 13).

    In my case, I use style.height instead of cols….

    Comment by Stanoo Chang — #
  3. I know this is an ancient post, but I wanted to add that I’m having the same problem with Opera and Konqueror. But there is a way to have the script working for the other browsers without needeing to make a special case to ignore Opera by comparing scrollHeight and offsetHeight rahter than clientHeight.

    Comment by Lyosha #
  4. Hi!

    Old post I know, and you’ve maybe moved on – but this was the starting point for just what I was looking for. I didn’t want to go down the mootools or jquery route because I have a lightweight form deployable over a mobile network and I wanted as little code as possible.

    Anyway – the flaw in your demo code is that it does not shrink after you delete text! If you type a lot and then delete it, you end up with an over size empty box.

    So the following addition when fix that:

    function grow() {
    if (this.scrollHeight > this.clientHeight ){
    this.rows += 1;
    }

    if (this.clientHeight > this.scrollHeight ){
    this.rows -= 1;
    }
    }

    It’s not perfect though!

  5. Also forget to mention:

    With a shrinking text box you need to be aware that onkeypress does not register backspace or delete keystrokes. This is obviously an issue because backspacing and deleting text does not fire the shrinking check.

    Instead you should use onkeydown which registers all keystrokes.

    document.getElementById(“grower”).onkeydown = grow;

  6. Hi,

    is there a way that a textarea auto-grows in a horizontal way?

  7. @Wilco: Yes. It should be enough to extend grow function with another if statement, where you replace Height with Width (e.g. scrollHeight becomes scrollWidth) and this.rows with this.cols.

    Side effect of this would be that textarea would stretch wider until you pressed Enter to skip to new line.

    @Kieran: Thanks for your comment. Demo is indeed incomplete.

    Comment by markos #
  8. The answer is simple:

    // JavaScript //
    textarea = new Object();

    textarea.expand = function(input){

    input.style.height = 0;
    input.style.height = (input.scrollHeight) + ‘px’;

    }

    // HTML //
    your text dynamically expands AND skrinks

    Comment by Michael McNally — #
  9. Sorry…the html was destroyed in my last message…here is is:

    // HTML //
    <textarea onkeyup=”textarea.expand(this);”>your text here</textarea&gt

    Comment by Michael McNally — #
  10. Thanks! I love this very simple and robust solution!
    However, I have a few suggestions:

    1. Consider replacing your “if” with a “while” loop. Normally this won’t matter, but if you cut and paste text into a text-area, or if your web-app already had lots of text in their then the if statement will only allow it to grow by one line instead of growing to fit.

    2. Consider using “onkeyup” rather than “onkeypress”. When I tested this on Firefox, the scroll bar is there after I press the return key, because of the order in which the client area is updated. “onkeyup” seems to produce cleaner results IMHO.

    Thanks!
    Chad

  11. Thank you for the post!! It is very helpful.
    I tested the enhancement that said Kieran Delaneu (to shrink the textarea), it worked in explorer but not in firefox. Do anyone know why? Thanks in advance!!

    Comment by Sandy — #
  12. I’m glad to see increased interest in this old post and there were many suggestions, some of which don’t work too well in practice.

    Hence I wrote a second version of script, which I tested on IE7, FF3, Opera10 and Safari4, incorporating ideas from comments.

    You can find and test it here.

    I’ve made few changes. Textarea should now not only grow, but also shrink and should work fine even if text as been pasted into it.

    I would also like to call attention to another change I did, which is that new function returns an event handler for mouseup and is not a handler function as such.

    To use you have to instantiate it like I did in example. You can provide a row limit under which it won’t shrink, which is 5 by default.

    Hopefully you’ll find this version of script more useful.

    Comment by markos #
  13. change the function to use while instead of if … works like a charm.
    //Auto grows / shrinks a text area based on size of input text
    function growTextArea(obj) {
    while (obj.scrollHeight > obj.clientHeight) {
    obj.rows += 1;
    }

    while (obj.clientHeight > obj.scrollHeight) {
    obj.rows -= 1;
    }
    }

    your text here

    Comment by Abe — #
  14. lost the text area :(
    <textarea onkeyup= “growTextArea(this);” onclick= “growTextArea(this);” onblur= “this.rows=1;”>your text here</textarea>

    Comment by Abe — #
  15. Another solution to get it work is creating a hidden div with same styles, and on each keyup – replace \n with (and quote ) in text, put it in that div box and get it’s height.

    Comment by StaTools #
  16. it can fix just by CSS.
    here’s my code.i thought it up 20 minutes ago.:p

    “this.style.height = ”” this is the most important part. it fixed the Firefox browser’s bug.

    CSS: overflow:hidden;
    width:XXXpx;
    enjoy it~:D

    Comment by JianXie — #
  17. can’t see the code!
    @_@..
    <textarea onpropertychange=”this.style.height = this.scrollHeight + ‘px’;” oninput=”this.style.height = ”;this.style.height = this.scrollHeight + ‘px’;”><⁄textarea>

    Comment by JianXie — #
  18. handy code, ThanKu @ Michael McNally

    Comment by kiramat — #

Sorry, the comment form is closed at this time.