Creating a textarea with auto-resize

JavascriptHtmlResizeHeightTextarea

Javascript Problem Overview


There was another thread about this, which I've tried. But there is one problem: the textarea doesn't shrink if you delete the content. I can't find any way to shrink it to the correct size - the clientHeight value comes back as the full size of the textarea, not its contents.

The code from that page is below:

function FitToContent(id, maxHeight)
{
   var text = id && id.style ? id : document.getElementById(id);
   if ( !text )
      return;

   var adjustedHeight = text.clientHeight;
   if ( !maxHeight || maxHeight > adjustedHeight )
   {
      adjustedHeight = Math.max(text.scrollHeight, adjustedHeight);
      if ( maxHeight )
         adjustedHeight = Math.min(maxHeight, adjustedHeight);
      if ( adjustedHeight > text.clientHeight )
         text.style.height = adjustedHeight + "px";
   }
}

window.onload = function() {
    document.getElementById("ta").onkeyup = function() {
      FitToContent( this, 500 )
    };
}

Javascript Solutions


Solution 1 - Javascript

A COMPLETE YET SIMPLE SOLUTION

Updated 2020-05-14 (Improved browser support for mobiles and tablets)

The following code will work:

  • On key input.
  • With pasted text (right click & ctrl+v).
  • With cut text (right click & ctrl+x).
  • With pre-loaded text.
  • With all textarea's (multiline textbox's) site wide.
  • With Firefox (v31-67 tested).
  • With Chrome (v37-74 tested).
  • With IE (v9-v11 tested).
  • With Edge (v14-v18 tested).
  • With IOS Safari.
  • With Android Browser.
  • With JavaScript strict mode.
  • Is w3c validated.
  • And is streamlined and efficient.

OPTION 1 (With jQuery)

This option requires jQuery and has been tested and is working with 1.7.2 - 3.6

Simple (Add this jquery code to your master script file and forget about it.)

$("textarea").each(function () {
  this.setAttribute("style", "height:" + (this.scrollHeight) + "px;overflow-y:hidden;");
}).on("input", function () {
  this.style.height = "auto";
  this.style.height = (this.scrollHeight) + "px";
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea placeholder="Type, paste, cut text here...">PRELOADED TEXT.
This javascript should now add better support for IOS browsers and Android browsers.</textarea>
<textarea placeholder="Type, paste, cut text here..."></textarea>

Test on jsfiddle


OPTION 2 (Pure JavaScript)

Simple (Add this JavaScript to your master script file and forget about it.)

const tx = document.getElementsByTagName("textarea");
for (let i = 0; i < tx.length; i++) {
  tx[i].setAttribute("style", "height:" + (tx[i].scrollHeight) + "px;overflow-y:hidden;");
  tx[i].addEventListener("input", OnInput, false);
}

function OnInput() {
  this.style.height = "auto";
  this.style.height = (this.scrollHeight) + "px";
}

<textarea placeholder="Type, paste, cut text here...">PRELOADED TEXT. This JavaScript should now add better support for IOS browsers and Android browsers.</textarea>
<textarea placeholder="Type, paste, cut text here..."></textarea>

Test on jsfiddle


OPTION 3 (jQuery Extension)

Useful if you want to apply further chaining to the textareas you want to be auto-sized.

jQuery.fn.extend({
  autoHeight: function () {
    function autoHeight_(element) {
      return jQuery(element)
        .css({ "height": "auto", "overflow-y": "hidden" })
        .height(element.scrollHeight);
    }
    return this.each(function() {
      autoHeight_(this).on("input", function() {
        autoHeight_(this);
      });
    });
  }
});

Invoke with $("textarea").autoHeight()


UPDATING TEXTAREA VIA JAVASCRIPT

When injecting content into a textarea via JavaScript append the following code to invoke the function in option 1.

$("textarea").trigger("input");

PRESET TEXTAREA HEIGHT

To fix the initial height of the textarea you will need to add an additional condition:

const txHeight = 16;
const tx = document.getElementsByTagName("textarea");

for (let i = 0; i < tx.length; i++) {
  if (tx[i].value == '') {
    tx[i].setAttribute("style", "height:" + txHeight + "px;overflow-y:hidden;");
  } else {
    tx[i].setAttribute("style", "height:" + (tx[i].scrollHeight) + "px;overflow-y:hidden;");
  }
  tx[i].addEventListener("input", OnInput, false);
}

function OnInput(e) {
  this.style.height = "auto";
  this.style.height = (this.scrollHeight) + "px";
}

<textarea placeholder="Type, paste, cut text here...">PRELOADED TEXT. This JavaScript should now add better support for IOS browsers and Android browsers.</textarea>
<textarea placeholder="Type, paste, cut text here..."></textarea>

Solution 2 - Javascript

This works for me (Firefox 3.6/4.0 and Chrome 10/11):

var observe;
if (window.attachEvent) {
    observe = function (element, event, handler) {
        element.attachEvent('on'+event, handler);
    };
}
else {
    observe = function (element, event, handler) {
        element.addEventListener(event, handler, false);
    };
}
function init () {
    var text = document.getElementById('text');
    function resize () {
        text.style.height = 'auto';
        text.style.height = text.scrollHeight+'px';
    }
    /* 0-timeout to get the already changed text */
    function delayedResize () {
        window.setTimeout(resize, 0);
    }
    observe(text, 'change',  resize);
    observe(text, 'cut',     delayedResize);
    observe(text, 'paste',   delayedResize);
    observe(text, 'drop',    delayedResize);
    observe(text, 'keydown', delayedResize);

    text.focus();
    text.select();
    resize();
}

textarea {
    border: 0 none white;
    overflow: hidden;
    padding: 0;
    outline: none;
    background-color: #D0D0D0;
}

<body onload="init();">
<textarea rows="1" style="height:1em;" id="text"></textarea>
</body>

If you want try it on jsfiddle It starts with a single line and grows only the exact amount necessary. It is ok for a single textarea, but I wanted to write something where I would have many many many such textareas (about as much as one would normally have lines in a large text document). In that case it is really slow. (In Firefox it's insanely slow.) So I really would like an approach that uses pure CSS. This would be possible with contenteditable, but I want it to be plaintext-only.

Solution 3 - Javascript

jQuery solution adjust the css to match your requirements

css...

div#container textarea {
    min-width: 270px;
    width: 270px;
    height: 22px;
    line-height: 24px;
    min-height: 22px;
    overflow-y: hidden; /* fixes scrollbar flash - kudos to @brettjonesdev */
    padding-top: 1.1em; /* fixes text jump on Enter keypress */
}

javascript...

// auto adjust the height of
$('#container').delegate( 'textarea', 'keydown', function (){
    $(this).height( 0 );
    $(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keydown();

OR alternative for jQuery 1.7+...

// auto adjust the height of
$('#container').on( 'keyup', 'textarea', function (){
    $(this).height( 0 );
    $(this).height( this.scrollHeight );
});
$('#container').find( 'textarea' ).keyup();

I've created a fiddle with the absolute minimum styling as a starting point for your experiments... http://jsfiddle.net/53eAy/951/

Solution 4 - Javascript

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Textarea autoresize</title>
	<style>
	textarea {
		overflow: hidden;
	}
	</style>
	<script>
    function resizeTextarea(ev) {
        this.style.height = '24px';
        this.style.height = this.scrollHeight + 12 + 'px';
    }

    var te = document.querySelector('textarea');
    te.addEventListener('input', resizeTextarea);
    </script>
</head>
<body>
	<textarea></textarea>
</body>
</html>

Tested in Firefox 14 and Chromium 18. The numbers 24 and 12 are arbitrary, test to see what suits you best.

You could do without the style and script tags, but it becomes a bit messy imho (this is old style HTML+JS and is not encouraged).

<textarea style="overflow: hidden" onkeyup="this.style.height='24px'; this.style.height = this.scrollHeight + 12 + 'px';"></textarea>

Edit: modernized code. Changed onkeyup attribute to addEventListener.
Edit: keydown works better than keyup
Edit: declare function before using
Edit: input works better than keydown (thnx @WASD42 & @MA-Maddin)

jsfiddle

Solution 5 - Javascript

The best solution (works and is short) for me is:

    $(document).on('input', 'textarea', function () {
        $(this).outerHeight(38).outerHeight(this.scrollHeight); // 38 or '1em' -min-height
    }); 

It works like a charm without any blinking with paste (with mouse also), cut, entering and it shrinks to the right size.

Please take a look at jsFiddle.

Solution 6 - Javascript

If you don’t need to support IE8 you can use the input event:

var resizingTextareas = [].slice.call(document.querySelectorAll('textarea[autoresize]'));

resizingTextareas.forEach(function(textarea) {
  textarea.addEventListener('input', autoresize, false);
});

function autoresize() {
  this.style.height = 'auto';
  this.style.height = this.scrollHeight+'px';
  this.scrollTop = this.scrollHeight;
  window.scrollTo(window.scrollLeft,(this.scrollTop+this.scrollHeight));
}

Now you only need to add some CSS and you are done:

textarea[autoresize] {
  display: block;
  overflow: hidden;
  resize: none;
}

Usage:

<textarea autoresize>Type here and I’ll resize.</textarea>

You can read more about how it works on my blog post.

Solution 7 - Javascript

Found an one liner from here;

<textarea name="text" oninput="this.style.height = ''; this.style.height = this.scrollHeight +'px'"></textarea>

Solution 8 - Javascript

You're using the higher value of the current clientHeight and the content scrollHeight. When you make the scrollHeight smaller by removing content, the calculated area can't get smaller because the clientHeight, previously set by style.height, is holding it open. You could instead take a max() of scrollHeight and a minimum height value you have predefined or calculated from textarea.rows.

In general you probably shouldn't really rely on scrollHeight on form controls. Apart from scrollHeight being traditionally less widely-supported than some of the other IE extensions, HTML/CSS says nothing about how form controls are implemented internally and you aren't guaranteed scrollHeight will be anything meaningful. (Traditionally some browsers have used OS widgets for the task, making CSS and DOM interaction on their internals impossible.) At least sniff for scrollHeight/clientHeight's existance before trying to enable the effect.

Another possible alternative approach to avoid the issue if it's important that it work more widely might be to use a hidden div sized to the same width as the textarea, and set in the same font. On keyup, you copy the text from the textarea to a text node in hidden div (remembering to replace '\n' with a line break, and escape '<'/'&' properly if you're using innerHTML). Then simply measuring the div's offsetHeight will give you the height you need.

Solution 9 - Javascript

autosize

https://github.com/jackmoore/autosize

Just works, standalone, is popular (3.0k+ GitHub stars as of October 2018), available on cdnjs) and lightweight (~3.5k). Demo:

<textarea id="autosize" style="width:200px;">a

J b c

BTW, if you are using the ACE editor, use maxLines: Infinity: https://stackoverflow.com/questions/11584061/automatically-adjust-height-to-contents-in-ace-cloud9-editor

Solution 10 - Javascript

Has anyone considered contenteditable? No messing around with scrolling,a nd the only JS I like about it is if you plan on saving the data on blur... and apparently, it's compatible on all of the popular browsers : http://caniuse.com/#feat=contenteditable

Just style it to look like a text box, and it autosizes... Make its min-height the preferred text height and have at it.

What's cool about this approach is that you can save and tags on some of the browsers.

http://jsfiddle.net/gbutiri/v31o8xfo/

var _auto_value = '';
$(document).on('blur', '.autosave', function(e) {
  var $this = $(this);
  if ($this.text().trim() == '') {
    $this.html('');
  }

  // The text is here. Do whatever you want with it.
  $this.addClass('saving');

  if (_auto_value !== $this.html() || $this.hasClass('error')) {

    // below code is for example only.
    $.ajax({
      url: '/echo/json/?action=xyz_abc',
      data: 'data=' + $this.html(),
      type: 'post',
      datatype: 'json',
      success: function(d) {
        console.log(d);
        $this.removeClass('saving error').addClass('saved');
        var k = setTimeout(function() {
          $this.removeClass('saved error')
        }, 500);
      },
      error: function() {
        $this.removeClass('saving').addClass('error');
      }
    });
  } else {
    $this.removeClass('saving');
  }
}).on('focus mouseup', '.autosave', function() {
  var $this = $(this);
  if ($this.text().trim() == '') {
    $this.html('');
  }
  _auto_value = $this.html();
}).on('keyup', '.autosave', function(e) {
  var $this = $(this);
  if ($this.text().trim() == '') {
    $this.html('');
  }
});

body {
  background: #3A3E3F;
  font-family: Arial;
}

label {
  font-size: 11px;
  color: #ddd;
}

.autoheight {
  min-height: 16px;
  font-size: 16px;
  margin: 0;
  padding: 10px;
  font-family: Arial;
  line-height: 20px;
  box-sizing: border-box;
  -o-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  overflow: hidden;
  display: block;
  resize: none;
  border: 0;
  outline: none;
  min-width: 200px;
  background: #ddd;
  max-height: 400px;
  overflow: auto;
}

.autoheight:hover {
  background: #eee;
}

.autoheight:focus {
  background: #fff;
}

.autosave {
  -webkit-transition: all .2s;
  -moz-transition: all .2s;
  transition: all .2s;
  position: relative;
  float: none;
}

.autoheight * {
  margin: 0;
  padding: 0;
}

.autosave.saving {
  background: #ff9;
}

.autosave.saved {
  background: #9f9;
}

.autosave.error {
  background: #f99;
}

.autosave:hover {
  background: #eee;
}

.autosave:focus {
  background: #fff;
}

[contenteditable=true]:empty:before {
  content: attr(placeholder);
  color: #999;
  position: relative;
  top: 0px;
  /*
    For IE only, do this:
    position: absolute;
    top: 10px;
    */
  cursor: text;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>Your Name</label>
<div class="autoheight autosave contenteditable" contenteditable="true" placeholder="Your Name"></div>

Solution 11 - Javascript

As a different approach, you can use a <span> which adjusts its size automatically. You will need make it editable by adding the contenteditable="true" property and you're done:

div {
  width: 200px;
}

span {
  border: 1px solid #000;
  padding: 5px;
}

<div>
  <span contenteditable="true">This text can be edited by the user</span>
</div>

The only issue with this approach is that if you want to submit the value as part of the form, you'll have to do so by yourself in JavaScript. Doing so is relatively easy. For example, you can add a hidden field and in the onsubmit event of the form assign the value of the span to the hidden field which will be then automatically submitted with the form.

Solution 12 - Javascript

There is a slightly different approach.

<div style="position: relative">
  <pre style="white-space: pre-wrap; word-wrap: break-word"></pre>
  <textarea style="position: absolute; top: 0; left: 0; width: 100%; height: 100%"></textarea>
</div>

The idea is to copy the text from textarea into the pre and let CSS make sure that they have the same size.

The benefit is that frameworks present simple tools to move text around without touching any events. Namely, in AngularJS you would add a ng-model="foo" ng-trim="false" to the textarea and ng-bind="foo + '\n'" to the pre. See a fiddle.

Just make sure that pre has the same font size as the textarea.

Solution 13 - Javascript

I used the following code for multiple textareas. Working fine in Chrome 12, Firefox 5 and IE 9, even with delete, cut and paste actions performed in the textareas.

function attachAutoResizeEvents() {
  for (i = 1; i <= 4; i++) {
    var txtX = document.getElementById('txt' + i)
    var minH = txtX.style.height.substr(0, txtX.style.height.indexOf('px'))
    txtX.onchange = new Function("resize(this," + minH + ")")
    txtX.onkeyup = new Function("resize(this," + minH + ")")
    txtX.onchange(txtX, minH)
  }
}

function resize(txtX, minH) {
  txtX.style.height = 'auto' // required when delete, cut or paste is performed
  txtX.style.height = txtX.scrollHeight + 'px'
  if (txtX.scrollHeight <= minH)
    txtX.style.height = minH + 'px'
}
window.onload = attachAutoResizeEvents

textarea {
  border: 0 none;
  overflow: hidden;
  outline: none;
  background-color: #eee
}

<textarea style='height:100px;font-family:arial' id="txt1"></textarea>
<textarea style='height:125px;font-family:arial' id="txt2"></textarea>
<textarea style='height:150px;font-family:arial' id="txt3"></textarea>
<textarea style='height:175px;font-family:arial' id="txt4"></textarea>

Solution 14 - Javascript

The following works for cutting, pasting, etc., regardless of whether those actions are from the mouse, a keyboard shortcut, selecting an option from a menu bar ... several answers take a similar approach but they don't account for box-sizing, which is why they incorrectly apply the style overflow: hidden.

I do the following, which also works well with max-height and rows for minimum and maximum height.

function adjust() {
  var style = this.currentStyle || window.getComputedStyle(this);
  var boxSizing = style.boxSizing === 'border-box'
      ? parseInt(style.borderBottomWidth, 10) +
        parseInt(style.borderTopWidth, 10)
      : 0;
  this.style.height = '';
  this.style.height = (this.scrollHeight + boxSizing) + 'px';
};

var textarea = document.getElementById("ta");
if ('onpropertychange' in textarea) { // IE
  textarea.onpropertychange = adjust;
} else if ('oninput' in textarea) {
  textarea.oninput = adjust;
}
setTimeout(adjust.bind(textarea));

textarea {
  resize: none;
  max-height: 150px;
  border: 1px solid #999;
  outline: none;
  font: 18px sans-serif;
  color: #333;
  width: 100%;
  padding: 8px 14px;
  box-sizing: border-box;
}

<textarea rows="3" id="ta">
Try adding several lines to this.
</textarea>

For absolute completeness, you should call the adjust function in a few more circumstances:

  1. Window resize events, if the width of the textarea changes with window resizing, or other events that change the width of the textarea
  2. When the textarea's display style attribute changes, e.g. when it goes from none (hidden) to block
  3. When the value of the textarea is changed programmatically

Note that using window.getComputedStyle or getting currentStyle can be somewhat computationally expensive, so you may want to cache the result instead.

Works for IE6, so I really hope that's good enough support.

Solution 15 - Javascript

A bit corrections. Works perfectly in Opera

  $('textarea').bind('keyup keypress', function() {
      $(this).height('');
      var brCount = this.value.split('\n').length;
      this.rows = brCount+1; //++ To remove twitching
      var areaH = this.scrollHeight,
          lineHeight = $(this).css('line-height').replace('px',''),
          calcRows = Math.floor(areaH/lineHeight);
      this.rows = calcRows;
  });

Solution 16 - Javascript

Here is an angularjs directive for panzi's answer.

 module.directive('autoHeight', function() {
    	return {
    		restrict: 'A',
    		link: function(scope, element, attrs) {
    			element = element[0];
    			var resize = function(){
    				element.style.height = 'auto';
    				element.style.height = (element.scrollHeight)+'px';
    			};
    			element.addEventListener('change', resize, false);
    			element.addEventListener('cut',    resize, false);
    			element.addEventListener('paste',  resize, false);
    			element.addEventListener('drop',   resize, false);
    			element.addEventListener('keydown',resize, false);
    			
    			setTimeout(resize, 100);
    		}
    	};
    });

HTML:

<textarea ng-model="foo" auto-height></textarea>

Solution 17 - Javascript

I know a short and correct way of implementing this with jquery.No extra hidden div needed and works in most browser

<script type="text/javascript">$(function(){
$("textarea").live("keyup keydown",function(){
var h=$(this);
h.height(60).height(h[0].scrollHeight);//where 60 is minimum height of textarea
});});

</script>

Solution 18 - Javascript

An even simpler, cleaner approach is this:

// adjust height of textarea.auto-height
$(document).on( 'keyup', 'textarea.auto-height', function (e){
    $(this).css('height', 'auto' ); // you can have this here or declared in CSS instead
    $(this).height( this.scrollHeight );
}).keyup();

// and the CSS

textarea.auto-height {
    resize: vertical;
    max-height: 600px; /* set as you need it */
    height: auto;      /* can be set here of in JS */
    overflow-y: auto;
    word-wrap:break-word
}

All that is needed is to add the .auto-height class to any textarea you want to target.

Tested in FF, Chrome and Safari. Let me know if this doesn't work for you, for any reason. But, this is the cleanest and simplest way I've found this to work. And it works great! :D

Solution 19 - Javascript

I Don't know if anyone mention this way but in some cases it's possible to resize the height with rows Attribute

textarea.setAttribute('rows',breaks);

Demo

Solution 20 - Javascript

You can use JQuery to expand the textarea while typing:

$(document).find('textarea').each(function () {
  var offset = this.offsetHeight - this.clientHeight;

  $(this).on('keyup input focus', function () {
    $(this).css('height', 'auto').css('height', this.scrollHeight + offset);
  });
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div>
<textarea name="note"></textarea>
<div>

Solution 21 - Javascript

Those who want to achieve the same in new versions of Angular.

Grab textArea elementRef.

@ViewChild('textArea', { read: ElementRef }) textArea: ElementRef;

public autoShrinkGrow() {
    textArea.style.overflow = 'hidden';
    textArea.style.height = '0px';
    textArea.style.height = textArea.scrollHeight + 'px';
}

<textarea (keyup)="autoGrow()" #textArea></textarea>

I am also adding another use case that may come handy some users reading the thread, when user want to increase the height of text-area to certain height and then have overflow:scroll on it, above method can be extended to achieve the mentioned use-case.

  public autoGrowShrinkToCertainHeight() {
    const textArea = this.textArea.nativeElement;
    if (textArea.scrollHeight > 77) {
      textArea.style.overflow = 'auto';
      return;
    }
    else {
      textArea.style.overflow = 'hidden';
      textArea.style.height = '0px';
      textArea.style.height = textArea.scrollHeight + 'px';
    }
  }

Solution 22 - Javascript

Some of the answers here don't account for padding.

Assuming you have a maxHeight you don't want to go over, this worked for me:

    // obviously requires jQuery

    // element is the textarea DOM node

    var $el = $(element);
    // inner height is height + padding
    // outerHeight includes border (and possibly margins too?)
    var padding = $el.innerHeight() - $el.height();
    var originalHeight = $el.height();

    // XXX: Don't leave this hardcoded
    var maxHeight = 300;

    var adjust = function() {
        // reset it to the original height so that scrollHeight makes sense
        $el.height(originalHeight);

        // this is the desired height (adjusted to content size)
        var height = element.scrollHeight - padding;

        // If you don't want a maxHeight, you can ignore this
        height = Math.min(height, maxHeight);

        // Set the height to the new adjusted height
        $el.height(height);
    }

    // The input event only works on modern browsers
    element.addEventListener('input', adjust);

Solution 23 - Javascript

This code works for pasting and select delete also.

onKeyPressTextMessage = function(){
			var textArea = event.currentTarget;
    	textArea.style.height = 'auto';
    	textArea.style.height = textArea.scrollHeight + 'px';
};

<textarea onkeyup="onKeyPressTextMessage(event)" name="welcomeContentTmpl" id="welcomeContent" onblur="onblurWelcomeTitle(event)" rows="2" cols="40" maxlength="320"></textarea>

Here is the JSFiddle

Solution 24 - Javascript

I recommend the javascript library from http://javierjulio.github.io/textarea-autosize.

Per comments, add example codeblock on plugin usage:

<textarea class="js-auto-size" rows="1"></textarea>

<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="jquery.textarea_autosize.min.js"></script>
<script>
$('textarea.js-auto-size').textareaAutoSize();
</script>

Minimum required CSS:

textarea {
  box-sizing: border-box;
  max-height: 160px; // optional but recommended
  min-height: 38px;
  overflow-x: hidden; // for Firefox (issue #5)
}

Solution 25 - Javascript

None of the answers seem to work. But this one works for me: https://coderwall.com/p/imkqoq/resize-textarea-to-fit-content

$('#content').on( 'change keyup keydown paste cut', 'textarea', function (){
    $(this).height(0).height(this.scrollHeight);
}).find( 'textarea' ).change();

Solution 26 - Javascript

MakeTextAreaResisable that uses qQuery

function MakeTextAreaResisable(id) {
	var o = $(id);
	o.css("overflow-y", "hidden");

	function ResizeTextArea() {
		o.height('auto');
		o.height(o[0].scrollHeight);
	}

	o.on('change', function (e) {
		ResizeTextArea();
	});

	o.on('cut paste drop keydown', function (e) {
		window.setTimeout(ResizeTextArea, 0);
	});

	o.focus();
	o.select();
	ResizeTextArea();
}

Solution 27 - Javascript

my implementation is very simple, count the number of lines in the input (and minimum 2 rows to show that it's a textarea):

textarea.rows = Math.max(2, textarea.value.split("\n").length) // # oninput

full working example with stimulus: https://jsbin.com/kajosolini/1/edit?html,js,output

(and this works with the browser's manual resize handle for instance)

Solution 28 - Javascript

Accepted answer is working fine. But that is lot of code for this simple functionality. The below code will do the trick.

   $(document).on("keypress", "textarea", function (e) {
    var height = $(this).css("height");
    var iScrollHeight = $(this).prop("scrollHeight");
    $(this).css('height',iScrollHeight);
    });

Solution 29 - Javascript

If scrollHeight could be trusted, then:

textarea.onkeyup=function() {
  this.style.height='';
  this.rows=this.value.split('\n').length;
  this.style.height=this.scrollHeight+'px';
}

Solution 30 - Javascript

Here is what I did while using MVC HTML Helper for TextArea. I had quite a few of textarea elements so had to distinguish them using Model Id.

 @Html.TextAreaFor(m => m.Text, 2, 1, new { id = "text" + Model.Id, onkeyup = "resizeTextBox(" + Model.Id + ");" })

and in script added this:

   function resizeTextBox(ID) {            
        var text = document.getElementById('text' + ID);
        text.style.height = 'auto';
        text.style.height = text.scrollHeight + 'px';            
    }

I have tested it on IE10 and Firefox23

Solution 31 - Javascript

The Best way I found:

$("textarea.auto-grow").each( function(){
	$(this).keyup(function(){
		$(this).height( $(this)[0].scrollHeight - Number( $(this).css("font-size").replace("px", "") ) );
	});
});

Other ways has a font-size bug.

Thats why this is the best.

Solution 32 - Javascript

for Angular 2+, just do this

<textarea (keydown)="resize($event)"></textarea>


resize(e) {
    setTimeout(() => {
      e.target.style.height = 'auto';
      e.target.style.height = (e.target.scrollHeight)+'px';
    }, 0);
  }

textarea {
  resize: none;
  overflow: hidden;
}

Solution 33 - Javascript

An example implementation with React:

const {
  useLayoutEffect,
  useState,
  useRef
} = React;

const TextArea = () => {
  const ref = useRef();
  const [value, setValue] = useState('Some initial text that both wraps and uses\nnew\nlines');

  // This only tracks the auto-sized height so we can tell if the user has manually resized
  const autoHeight = useRef();

  useLayoutEffect(() => {
    if (!ref.current) {
      return;
    }

    if (
      autoHeight.current !== undefined &&
      ref.current.style.height !== autoHeight.current
    ) {
      // don't auto size if the user has manually changed the height
      return;
    }

    ref.current.style.height = "auto";
    ref.current.style.overflow = "hidden";
    const next = `${ref.current.scrollHeight}px`;
    ref.current.style.height = next;
    autoHeight.current = next;
    ref.current.style.overflow = "auto";
  }, [value, ref, autoHeight]);


  return (
    <textarea
      ref={ref}
      style={{
        resize: 'vertical',
        minHeight: '1em',
      }}
      value={value}
      onChange={event => setValue(event.target.value)}
    />
  );
}

ReactDOM.render(<TextArea />, document.getElementById('app'))

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="app"></div>

Solution 34 - Javascript

For those who want the textarea to be auto resized on both width and height:

HTML:

<textarea class='textbox'></textarea>
<div>
  <span class='tmp_textbox'></span>
</div>

CSS:

.textbox,
.tmp_textbox {
  font-family: 'Arial';
  font-size: 12px;
  resize: none;
  overflow:hidden;
}

.tmp_textbox {
  display: none;
}

jQuery:

$(function(){
  //alert($('.textbox').css('padding'))
  $('.textbox').on('keyup change', checkSize)
  $('.textbox').trigger('keyup')
  
  function checkSize(){
    var str = $(this).val().replace(/\r?\n/g, '<br/>');
    $('.tmp_textbox').html( str )
    console.log($(this).val())
    
    var strArr = str.split('<br/>')
    var row = strArr.length
    $('.textbox').attr('rows', row)
    $('.textbox').width( $('.tmp_textbox').width() + parseInt($('.textbox').css('padding')) * 2 + 10 )
  }
})

Codepen:

http://codepen.io/anon/pen/yNpvJJ

Cheers,

Solution 35 - Javascript

The jQuery solution is to set the height of the textarea to 'auto', check the scrollHeight and then adapt the height of the textarea to that, every time a textarea changes (JSFiddle):

$('textarea').on( 'input', function(){
	$(this).height( 'auto' ).height( this.scrollHeight );
});

If you're dynamically adding textareas (through AJAX or whatever), you can add this in your $(document).ready to make sure all textareas with class 'autoheight' are kept to the same height as their content:

$(document).on( 'input', 'textarea.autoheight', function() {
	$(this).height( 'auto' ).height( this.scrollHeight );
});

Tested and working in Chrome, Firefox, Opera and IE. Also supports cut and paste, long words, etc.

Solution 36 - Javascript

Just use <pre> </pre> with some styles like:

    pre {
        font-family: Arial, Helvetica, sans-serif;
        white-space: pre-wrap;
        word-wrap: break-word;
        font-size: 12px;
        line-height: 16px;
    }

Solution 37 - Javascript

You can use this piece of code to compute the number of rows a textarea needs:

textarea.rows = 1;
    if (textarea.scrollHeight > textarea.clientHeight)
      textarea.rows = textarea.scrollHeight / textarea.clientHeight;

Compute it on input and window:resize events to get auto-resize effect. Example in Angular:

Template code:

<textarea rows="1" reAutoWrap></textarea>

auto-wrap.directive.ts

import { Directive, ElementRef, HostListener } from '@angular/core';

@Directive({
  selector: 'textarea[reAutoWrap]',
})
export class AutoWrapDirective {

  private readonly textarea: HTMLTextAreaElement;

  constructor(el: ElementRef) {
    this.textarea = el.nativeElement;
  }

  @HostListener('input') onInput() {
    this.resize();
  }

  @HostListener('window:resize') onChange() {
    this.resize();
  }

  private resize() {
    this.textarea.rows = 1;
    if (this.textarea.scrollHeight > this.textarea.clientHeight)
      this.textarea.rows = this.textarea.scrollHeight / this.textarea.clientHeight;
  }

}

Solution 38 - Javascript

Native Javascript solution without flickering in Firefox and faster than method withclientHeight...

  1. Add div.textarea selector to all your selectors containing textarea. Do not forget to add box-sizing: border-box;

  2. Include this script:

    function resizeAll() { var textarea=document.querySelectorAll('textarea'); for(var i=textarea.length-1; i>=0; i--) resize(textarea[i]); }

    function resize(textarea) { var div = document.createElement("div"); div.setAttribute("class","textarea"); div.innerText=textarea.value+"\r\n"; div.setAttribute("style","width:"+textarea.offsetWidth+'px;display:block;height:auto;left:0px;top:0px;position:fixed;z-index:-200;visibility:hidden;word-wrap:break-word;overflow:hidden;'); textarea.form.appendChild(div); var h=div.offsetHeight; div.parentNode.removeChild(div); textarea.style.height=h+'px'; }

    function resizeOnInput(e) { var textarea=document.querySelectorAll('textarea'); for(var i=textarea.length-1; i>=0; i--) textarea[i].addEventListener("input",function(e){resize(e.target); return false;},false); }

    window.addEventListener("resize",function(){resizeAll();}, false); window.addEventListener("load",function(){resizeAll();}, false); resizeOnInput();

Tested on IE11, Firefox and Chrome.

This solution creates div similar to your textarea including internal text and measures height.

Solution 39 - Javascript

I created a small (7kb) custom element that deals with all of this resizing logic for you.

It works everywhere, because it's implemented as a custom element. Including: Virtual DOMs (React, Elm, etc.), server-side rendered stuff like PHP and plain boring HTML files.

Apart from listening for the input event, it also has a timer that fires every 100ms to make sure things are still working in case the text content changes by some other means.

Here's how it works:

// At the top of one of your Javascript files
import "autoheight-textarea";

or include as a script tag

<script src="//cdn.jsdelivr.net/npm/[email protected]/dist/main.min.js"></script>

then just wrap your textarea elements like so

HTML File

<autoheight-textarea>
  <textarea rows="4" placeholder="Type something"></textarea>
<autoheight-textarea>

React.js Component

const MyComponent = () => {
  return (
    <autoheight-textarea>
      <textarea rows={4} placeholder="Type something..." />
    </autoheight-textarea>
  );
}

Here's a basic demo on Codesandbox: https://codesandbox.io/s/unruffled-http-2vm4c

And you can grab the package here: https://www.npmjs.com/package/autoheight-textarea

If you're just curious to see the resizing logic, you can take a look at this function: https://github.com/Ahrengot/autoheight-textarea/blob/master/src/index.ts#L74-L85

Solution 40 - Javascript

This is a jQuery version of Moussawi7's answer.

$(function() {
  $("textarea.auto-grow").on("input", function() {
    var element = $(this)[0];
    element.style.height = "5px";
    element.style.height = (element.scrollHeight) + "px";
  });
})

textarea {
  resize: none;
  overflow: auto;
  width: 100%;
  min-height: 50px;
  max-height: 150px;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea class="auto-grow"></textarea>

Solution 41 - Javascript

I know I'm late to this party but the simplest solution I've come across is to split your text area content on new line characters and update the rows for the textarea element.

<textarea id="my-text-area"></textarea>

<script>
  $(function() {
    const txtArea = $('#my-text-area')
    const val = txtArea.val()
    const rowLength = val.split('\n')
    txtArea.attr('rows', rowLength)
  })
</script>

Solution 42 - Javascript

This is a row based approach that lets you set a maximum number of rows for the textarea after which the textarea will show scrollbar. Besides adjusting its height in the form of rows attribute, this will also auto-expand its width while being typed or doing things like cut and paste.

If the textarea doesn't have any content but a placeholder, it will adjust its width and height as per the placeholder text.

One drawback to this version is that it will continue increasing its width infinitely based on the text width. So, you will want to set a max-width value to the textarea. A simple max-width: 100%; will also do the trick. This width expanding feature is primarily based on input fields of type="text". You can read more about it in this answer.

const textarea = document.querySelector('textarea');

setTextareaWidthHeight(textarea);
textarea.addEventListener('input', setTextareaWidthHeight.bind(this, textarea));

function getInputWidth(element) {
    const text = element.value || element.placeholder;
    const elementStyle = window.getComputedStyle(element);
    const fontProperty = elementStyle.font;
    const horizontalBorder = parseFloat(elementStyle.borderLeftWidth) + parseFloat(elementStyle.borderRightWidth);
    const horizontalPadding = parseFloat(elementStyle.paddingLeft) + parseFloat(elementStyle.paddingRight);

    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    context.font = fontProperty;
    const textWidth = context.measureText(text).width;

    const totalWidth = horizontalBorder + horizontalPadding + textWidth + "px";
    return totalWidth;
}

function setTextareaWidthHeight(element) {
    // store minimum and maximum rows attribute value that should be imposed
    const minRows = 1;
    const maxRows = 5;

    // store initial inline overflow property value in a variable for later reverting to original condition
    const initialInlineOverflowY = element.style.overflowY;

    // change overflow-y property value to hidden to overcome inconsistent width differences caused by any scrollbar width
    element.style.overflowY = 'hidden';

    const totalWidth = getInputWidth(element);
    element.style.width = totalWidth;

    let rows = minRows;
    element.setAttribute("rows", rows);

    while (rows <= maxRows && element.scrollHeight !== element.clientHeight) {
        element.setAttribute("rows", rows);
        rows++;
    }

    // change overflow to its original condition
    if (initialInlineOverflowY) {
        element.style.overflowY = initialInlineOverflowY;
    } else {
        element.style.removeProperty("overflow-y");
    }
}

textarea {
    max-width: 100%;
}

<textarea placeholder="Lorem ipsum dolor sit amet"></textarea>

Solution 43 - Javascript

There is a definitive answer here:

https://stackoverflow.com/questions/70543526/backspace-increases-value-of-scrollheight

It uses modern ES6 syntax and solves the issues around accurate resizing when content is added or removed. It solves the issue around the constantly-changing scrollheight values.

Solution 44 - Javascript

This is a simple way to do using React.

...
const textareaRef = useRef();

const handleChange = (e) => {
  textareaRef.current.style.height = "auto";
  textareaRef.current.style.height = textareaRef.current.scrollHeight + "px";
};

return <textarea ref={textareaRef} onChange={handleChange} />;

Solution 45 - Javascript

I have tested script in common browsers, and it failed in Chrome and Safari. It is because of constantly updatable scrollHeight variable.

I have applied DisgruntledGoat script using jQuery and added chrome fix

function fitToContent(/* JQuery */text, /* Number */maxHeight) {
	var adjustedHeight = text.height();
	var relative_error = parseInt(text.attr('relative_error'));
	if (!maxHeight || maxHeight > adjustedHeight) {
		adjustedHeight = Math.max(text[0].scrollHeight, adjustedHeight);
		if (maxHeight)
			adjustedHeight = Math.min(maxHeight, adjustedHeight);
		if ((adjustedHeight - relative_error) > text.height()) {
			text.css('height', (adjustedHeight - relative_error) + "px");
			// chrome fix
			if (text[0].scrollHeight != adjustedHeight) {
				var relative = text[0].scrollHeight - adjustedHeight;
				if (relative_error != relative) {
					text.attr('relative_error', relative + relative_error);
				}
			}
		}
	}
}

function autoResizeText(/* Number */maxHeight) {
	var resize = function() {
		fitToContent($(this), maxHeight);
	};
	$("textarea").attr('relative_error', 0);
	$("textarea").each(resize);
	$("textarea").keyup(resize).keydown(resize);
}

Solution 46 - Javascript

$('textarea').bind('keyup change', function() {
    var $this = $(this), $offset = this.offsetHeight;
    $offset > $this.height() && $offset < 300 ?
        $this.css('height ', $offset)
            .attr('rows', $this.val().split('\n').length)
            .css({'height' : $this.attr('scrollHeight'),'overflow' : 'hidden'}) :
        $this.css('overflow','auto');
});

Solution 47 - Javascript

I'm able to set the TextArea size in IE9 and Chrome with the following jQuery function. It binds to the textarea objects from the selector defined in the $(document).ready() function.

function autoResize(obj, size) {
	obj.keyup(function () {
		if ($(this).val().length > size-1) {
			$(this).val( function() {
				$(this).height(function() {
					return this.scrollHeight + 13;
				});
				alert('The maximum comment length is '+size+' characters.');
				return $(this).val().substring(0, size-1);
			});
		}
		$(this).height(function() {
			if  ($(this).val() == '') {
				return 15;
			} else {
				$(this).height(15);
				return ($(this).attr('scrollHeight')-2);
			}
		});
	}).keyup();
}

In my $(document).ready() function I have the following call for all of my textarea calls on this page.

$('textarea').each( function() {
		autoResize($(this), 250);
});

Where 250 is the character limit on my text area. This will grow as large as the text size will allow (based on your character count and font size). It will also shrink your text area appropriately when you remove characters from your textarea or if the user pastes too much text initially.

Solution 48 - Javascript

You can use this code:

Coffescript:

jQuery.fn.extend autoHeightTextarea: ->
  autoHeightTextarea_ = (element) ->
    jQuery(element).css(
      'height': 'auto'
      'overflow-y': 'hidden').height element.scrollHeight

  @each ->
    autoHeightTextarea_(@).on 'input', ->
      autoHeightTextarea_ @

$('textarea_class_or_id`').autoHeightTextarea()

Javascript

jQuery.fn.extend({
  autoHeightTextarea: function() {
    var autoHeightTextarea_;
    autoHeightTextarea_ = function(element) {
      return jQuery(element).css({
        'height': 'auto',
        'overflow-y': 'hidden'
      }).height(element.scrollHeight);
    };
    return this.each(function() {
      return autoHeightTextarea_(this).on('input', function() {
        return autoHeightTextarea_(this);
      });
    });
  }
});

$('textarea_class_or_id`').autoHeightTextarea();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDisgruntledGoatView Question on Stackoverflow
Solution 1 - JavascriptDreamTeKView Answer on Stackoverflow
Solution 2 - JavascriptpanziView Answer on Stackoverflow
Solution 3 - JavascriptchimView Answer on Stackoverflow
Solution 4 - JavascriptGijsjanBView Answer on Stackoverflow
Solution 5 - JavascriptvatavaleView Answer on Stackoverflow
Solution 6 - JavascriptMax HoffmannView Answer on Stackoverflow
Solution 7 - Javascript17KView Answer on Stackoverflow
Solution 8 - JavascriptbobinceView Answer on Stackoverflow
Solution 9 - JavascriptCiro Santilli Путлер Капут 六四事View Answer on Stackoverflow
Solution 10 - JavascriptWebmaster GView Answer on Stackoverflow
Solution 11 - JavascriptRacil HilanView Answer on Stackoverflow
Solution 12 - JavascriptKarolis JuodelėView Answer on Stackoverflow
Solution 13 - JavascriptNikunj BhattView Answer on Stackoverflow
Solution 14 - JavascriptJoseph NieldsView Answer on Stackoverflow
Solution 15 - Javascriptartnik-proView Answer on Stackoverflow
Solution 16 - JavascriptchrmcpnView Answer on Stackoverflow
Solution 17 - Javascriptuser1432124View Answer on Stackoverflow
Solution 18 - JavascriptreviveView Answer on Stackoverflow
Solution 19 - Javascripth0mayunView Answer on Stackoverflow
Solution 20 - JavascriptMauricio SánchezView Answer on Stackoverflow
Solution 21 - JavascriptDivyanshu RawatView Answer on Stackoverflow
Solution 22 - JavascripthasenView Answer on Stackoverflow
Solution 23 - JavascriptKurenai KunaiView Answer on Stackoverflow
Solution 24 - Javascriptorange01View Answer on Stackoverflow
Solution 25 - JavascriptKim HomannView Answer on Stackoverflow
Solution 26 - JavascriptIgor KrupitskyView Answer on Stackoverflow
Solution 27 - JavascriptlocalhostdotdevView Answer on Stackoverflow
Solution 28 - Javascriptkarthik_krishView Answer on Stackoverflow
Solution 29 - JavascriptrrrView Answer on Stackoverflow
Solution 30 - JavascriptgunnerzView Answer on Stackoverflow
Solution 31 - JavascriptKarl ZillnerView Answer on Stackoverflow
Solution 32 - JavascriptJohansrkView Answer on Stackoverflow
Solution 33 - JavascriptChrisView Answer on Stackoverflow
Solution 34 - JavascriptGoon NguyenView Answer on Stackoverflow
Solution 35 - JavascriptpatrickView Answer on Stackoverflow
Solution 36 - JavascriptLiberView Answer on Stackoverflow
Solution 37 - JavascriptAndréView Answer on Stackoverflow
Solution 38 - Javascript18CView Answer on Stackoverflow
Solution 39 - JavascriptAhrengotView Answer on Stackoverflow
Solution 40 - JavascriptbafsarView Answer on Stackoverflow
Solution 41 - Javascriptrun.revelationsView Answer on Stackoverflow
Solution 42 - JavascriptarafatgaziView Answer on Stackoverflow
Solution 43 - JavascriptMark TyersView Answer on Stackoverflow
Solution 44 - JavascriptRicardo CanelasView Answer on Stackoverflow
Solution 45 - JavascriptView Answer on Stackoverflow
Solution 46 - JavascriptAlgorithmView Answer on Stackoverflow
Solution 47 - JavascriptMatthewView Answer on Stackoverflow
Solution 48 - JavascriptDarex1991View Answer on Stackoverflow