CSS Textarea that expands as you type text

58,169

Solution 1

This cannot be done with CSS alone. try the autogrow jquery plugin. https://github.com/jaz303/jquery-grab-bag/blob/master/javascripts/jquery.autogrow-textarea.js

You can also see autogrow demo here http://onehackoranother.com/projects/jquery/jquery-grab-bag/autogrow-textarea.html

It's lightweight and easy to use. Here's how it's done. Define your textarea id. Include the jquery js file before </body>. Then between script tags, issue the jquery command $("#txtInput").autoGrow();

<body>
    <textarea id="txtInput"></textarea>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script> 

<script>
    $("#txtInput").autogrow();
</script>
</body>

Solution 2

I know this is a little bit late, but I have to say there is a way to use <div> with contenteditable attribute to simulate desired behaviour.

.textareaElement {
  width: 300px;
  min-height: 17px;
  border: 1px solid #ccc;
  max-height: 150px;
  overflow-x: hidden;
  overflow-y: auto;
}
<div class="textareaElement" contenteditable></div>

Just set your min and max height, with proper overflow values, and you have fully functional pure CSS expanding textbox, that is also well supported.

enter image description here

Solution 3

This jQuery plugin is a really great one: http://www.jacklmoore.com/autosize

I've tested a bunch of these and this is by far the nicest. Also gives an example of using a CSS transition effect which is pretty slick.

Solution 4

**Note this is very similar to Woody's answer above but wanted to expand upon it a little and provide a running code example now that Stack allows us to embed them.

After reading through all of this and trying a couple of plugins, I found that none of this quite worked as I had hoped. I did the following using jquery, but can be done with javascript just as easily by grabbing the padding values instead of using inner height:

  • Set a minimum height on the textarea in CSS
  • Set overflow to hidden for vertical scrolling (I just wanted to expand vertically)
  • Set the height to the scroll height less padding on each keyup event if scroll height was higher than height + padding (innerHeight).
  • If scroll height was not taller, I re-set the height to 1, and then set the height to the scroll height less padding (to shrink the height). If you don't reset to a smaller height initially the scroll height won't shrink.

$(function() {
  $('#myTextArea').on('input keyup paste', function() {
    var $el = $(this),
        offset = $el.innerHeight() - $el.height();

    if ($el.innerHeight() < this.scrollHeight) {
      // Grow the field if scroll height is smaller
      $el.height(this.scrollHeight - offset);
    } else {
      // Shrink the field and then re-set it to the scroll height in case it needs to shrink
      $el.height(1);
      $el.height(this.scrollHeight - offset);
    }
  });
});
#myTextArea {
  width: 250px;
  min-height: 35px;
  overflow-y: hidden;
}
<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<textarea id="myTextArea" placeholder="Hit enter a few times, it should expand"></textarea>

Solution 5

You don't need a plugin for this. This works on textareas of any size, height or row size and will only work when the contents exceeds the textarea. Firstly set the overflow on your target textareas to hidden and resize to none, then add the following functionality to the textareas you want to autogrow. Not only will it increase the textarea's size as the user types, it'll also auto-shrink it when they delete stuff.

$('textarea').on('paste input', function () {
    if ($(this).outerHeight() > this.scrollHeight){
        $(this).height(1)
    }
    while ($(this).outerHeight() < this.scrollHeight + parseFloat($(this).css("borderTopWidth")) + parseFloat($(this).css("borderBottomWidth"))){
        $(this).height($(this).height() + 1)
    }
});

It works by measuring if the scroll height of the textarea is bigger than the outer height, which it only will be if there's more text than the textarea can hold - and it takes border size into account for higher accuracy. Using paste and input means it will only increase when the user physically changes the value of the textarea, as opposed to when they press any key. It's petty but a textarea shouldn't grow when somebody presses an arrow key or something.

It might be prudent to add a No JS option that re-enables overflow and resizing for those who don't have Javascript, else they'll be stuck with a tiny box.

Share:
58,169

Related videos on Youtube

Spencer
Author by

Spencer

Updated on August 12, 2021

Comments

  • Spencer
    Spencer almost 3 years

    I have a Textarea where users can input text. By default it has a height of 17px. However if users insert a large amount of text, I want the text area to expand accordingly. Is there a way to do this with CSS ? Thanks in advance!!

    • starbeamrainbowlabs
      starbeamrainbowlabs about 7 years
      Hasn't anyone come up with a jquery-free solution to this problem? :-(
  • Null Head
    Null Head about 11 years
    Why does the javascriptly link take me bet365.com!!
  • Manish Kumar
    Manish Kumar over 9 years
    what is the meaning of ||
  • Edward Newell
    Edward Newell about 9 years
    $('#textInput').autoGrow(); should be $(#txtInput).autogrow();
  • Woody Payne
    Woody Payne almost 9 years
    This doesn't work. It gives NaN as the rows on any of the four bound events. If there's no newline or there's no "row" attribute already on the textarea, you're trying to do maths with 'undefined'. So, this only works when there's actually new lines to work with... Which is never, because the moment you do anything in the field the bound events are setting the rows to NaN, preventing any further modification.
  • DigitalDan
    DigitalDan almost 9 years
    You're right, the textarea must have a "rows" attribute for my original code to work. I've added a guard (` || 1`) to cater for that.
  • Ning Liu
    Ning Liu almost 9 years
    I agree this is the best solution out there. Most importantly, it fixed this bug: When the textarea y-overflow is hidden, Chrome/Safari do not reflow the text to account for the space made available by removing the scrollbar. The autogrow jquery plugin marked as answer does not have this fix.
  • Sam
    Sam over 8 years
    @Manish, it's just the logical "OR" operator, but in this context, it's being used to default to 2 rows if the calculated length somehow evaluates to false.
  • H2ONOCK
    H2ONOCK over 8 years
    if you change Math.max to Math.round, the textarea will also shrink if you delete text.
  • Adas
    Adas almost 8 years
    It doesn't decrease after.
  • Felipe Alarcon
    Felipe Alarcon almost 7 years
    Great solution as I only care about Chrome support. Thanks!
  • Trevin Avery
    Trevin Avery over 6 years
    This is a great solution! The only complication is that when you press enter/return it places all of the new text into a <div> block. So the innerHTML becomes a text node followed by a bunch of <div>s.
  • Resource
    Resource about 6 years
    This works great for me with 'keyup paste input' - except in the case where I'm loading the data from a database. The textarea will expand when I click in it, but as initially displayed it will only show the first line. My JQuery is 'as-needed' so essentially non-existent. I've tried to add a few events e.g. 'ready', 'load' and a couple more but nothing seems to work. Anyone got any tips?
  • Stephen Tremaine
    Stephen Tremaine about 6 years
    There is probably a more elegant way to do this, but you can always fire the keyup event manually so the above code runs after you load your data from the database -- $('#test').keyup(); If it's a static page that is rendered server side with the database data in it, you can put the keyup event in the jquery ready function so it runs after jquery and other libraries are loaded -- $(function() { $('#test').keyup(); });
  • Resource
    Resource about 6 years
    Many thanks for the reply. I have tried the keyup without success - maybe because I have many instances of the textbox inside a ListView, and I identify them in the JS by class. I used $(".ExpandableText").keyup(); and also tried with single quotes. No-one's complained about the initial size yet. Only a matter of time though.
  • ekashking
    ekashking over 5 years
    It works just fine as long as you don't forget to include the jQuery library !!! Yarin jsfiddle is presented without it. But once you choose jQuery 1.9.1 in options, it's all good after.
  • Partho63
    Partho63 about 5 years
    Please provide some explanations with your code as well.
  • rajmobiapp
    rajmobiapp about 5 years
    Default text area 6 line that is 6 row. When you / user can type text inside text area automatically text area height is increasing. When you press key autosize() function triggered
  • rajmobiapp
    rajmobiapp about 5 years
    If you add extra jquery plugin others then waste of your time,application loading time taken maybe high
  • rajmobiapp
    rajmobiapp about 5 years
    Just try working fine for me. You try and modify based on your requirements.this very simple method
  • Manzur Khan
    Manzur Khan almost 5 years
    It's a lot hackier I would say
  • Admin
    Admin almost 5 years
    @ekashking i did not get that result.
  • N0XT
    N0XT over 4 years
    Yes! The code is relying in the scrollHeight basically. If you look the css, you 'll find "overflow-y: scroll", everytime the textarea overflows, text will go down, the scrollHeight will increase by the height of the text... So what it does is add the extra height of the scroll to the height of the textarea... To put it simple, the height of the text inside is added to the height of the textarea.
  • user3107036
    user3107036 over 3 years
    It works, but for some reason on my complex pages with many tables and textareas it is very slow, sometimes it pauses for a second or two after hitting the Enter key.
  • ram
    ram over 3 years
    I thought this was a great solution too, but if you are doing any manipulation of the text, contentEditable can quickly become a disaster as it does things very differently and the documentation is not great. If you just want a simple text input then, yes, but just be aware there are a lot of curve-balls w/ editableContent.