DisgruntledGoat
DisgruntledGoat

Reputation: 72510

Creating a textarea with auto-resize

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 )
    };
}

Upvotes: 544

Views: 733665

Answers (30)

Racil Hilan
Racil Hilan

Reputation: 25341

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: 0 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.

Upvotes: 12

Judah Gabriel Himango
Judah Gabriel Himango

Reputation: 60001

As of 2024, there's a new answer that doesn't need hacks or 3rd party libraries: the field-sizing attribute being added to text inputs as part of web standards. Details in the field-sizing standards proposal explainer.

Update April 2024: for more info, see CSS field-sizing on Chrome dev docs and field-sizing on MDN

With the new field-sizing style, you can instruct <textarea> or <input type="text"> to size themselves based on content:

textarea {
   field-sizing: content;
}

Chromium-based browsers are expected to ship this feature in Chrome 123, expected to arrive March 2024 timeframe.

Here's a quick code snippet to see if your browser supports this new standard:

// Let the user know whether field-sizing is supported.
const textArea = document.querySelector("textarea");
const resultSpan = document.querySelector("span");
resultSpan.innerText = ("fieldSizing" in textArea.style) ? '✅' : '❌'
textarea {
  field-sizing: content;
  min-width: 200px; /* optional: a minimum width, otherwise textarea can become very small with no content */
  max-height: 10lh; /* optional: after 10 lines, give a scrollbar */
}
<textarea>This textarea automatically grows based on its content</textarea>

<h1>Your browser's support for field sizing: <span></span></h1>

Upvotes: 31

DreamTeK
DreamTeK

Reputation: 34177

A COMPLETE YET SIMPLE SOLUTION

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 textareas (multiline textboxes) site wide.
  • With Firefox (v31-109 tested).
  • With Chrome (v37-108 tested).
  • With IE (v9-v11 tested).
  • With Edge (v14-v108 tested).
  • With IOS Safari.
  • With Android Browser.
  • With JavaScript strict mode.

OPTION 1 (With jQuery)

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

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

$("textarea").each(function () {
  this.style.height = this.scrollHeight + "px";
  this.style.overflowY = "hidden";
}).on("input", function () {
  this.style.height = "auto";
  this.style.height = this.scrollHeight + "px";
});
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.7.1.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.)

document.querySelectorAll("textarea").forEach(function(textarea) {
  textarea.style.height = textarea.scrollHeight + "px";
  textarea.style.overflowY = "hidden";

  textarea.addEventListener("input", function() {
    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 setAutoHeight(element) {
      jQuery(element).css({ height: 'auto', overflowY: 'hidden' });
      jQuery(element).height(element.scrollHeight);
    }

    return this.each(function() {
      setAutoHeight(this);
      jQuery(this).on("input", () => setAutoHeight(this));
    });
  }
});

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


UPDATING TEXTAREA VIA JAVASCRIPT

When injecting content into a textarea via JavaScript, append the following line of code to invoke the resize function.

jQuery

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

Pure JavaScript

document.querySelectorAll("textarea").forEach(t => t.dispatchEvent(new Event('input', { bubbles: true, cancelable: true })));

PRESET TEXTAREA HEIGHT

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

const txHeight = 16; // Preset initial height in pixels
const tx = document.getElementsByTagName("textarea");

for (let i = 0; i < tx.length; i++) {
  if (tx[i].value === '') {
    tx[i].style.height = txHeight + "px";
  } else {
    tx[i].style.height = tx[i].scrollHeight + "px";
  }
  tx[i].style.overflowY = "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>

Upvotes: 678

Matt
Matt

Reputation: 136

In modern browsers, no JS is needed anymore. Currently only works in Chrome and Edge

textarea {
  field-sizing: content;
}

Upvotes: 1

snnsnn
snnsnn

Reputation: 13600

You don't need overly complicated calculations or style manipulations. Here is a clear and concise way to do it:

  1. Add oninput event listener to the textarea element.
  2. Inside that listener, set rows attribute via currentTarget
const handleInput = (event) => {
  const lines = event.currentTarget.value.split(/\r\n|\r|\n/).length
  event.currentTarget.setAttribute('rows', lines.toString());
}

el.addEventListener('input', handleInput);

You can control the initial height using the very same way:

  1. Get the content
  2. Calculate the number of lines
  3. Set the rows attribute on the element.
const content = 'Some Content';
const lines = content.split(/\r\n|\r|\n/).length
el.setAttribute('rows', lines.toString());
el.innerHTML = content;

Here is an example demonstrating it:

const handleInput = (event) => {
  const lines = event.currentTarget.value.split(/\r\n|\r|\n/).length
  event.currentTarget.setAttribute('rows', lines.toString());
}

const el = document.createElement('textarea');
el.addEventListener('input', handleInput);

const content = 'Some Content';
const lines = content.split(/\r\n|\r|\n/).length
el.setAttribute('rows', lines.toString());
el.innerHTML = content;

document.body.appendChild(el);

Upvotes: -2

Reza Ghorbani
Reza Ghorbani

Reputation: 2876

Pure CSS solution:

textarea {
  form-sizing: content;
}

Warning: This is not supported in most browsers (e.g. firefox and safari), but support will likely increase in the coming months. I would wait until it is more widely available to use it.

Upvotes: 3

BIUBIU UP
BIUBIU UP

Reputation: 45

for Vue2 directives:

directives: {
  autoResize: {
    // autoResize
    inserted: (el) => {
      function OnInput() {
        el.style.height = 'auto';
        el.style.height = (this.scrollHeight) + "px";
      }
      el.setAttribute("style", "height:" + (el.scrollHeight) + "px;overflow-y:hidden;");
      el.addEventListener("input", OnInput, false);
    }
  }
}

Upvotes: 0

ishandutta2007
ishandutta2007

Reputation: 18184

If you are using react I would recommend TextareaAutosize library. It's nothing but simple textarea under the hood but frees you of the hassles of styling issues and if you are already using the styling for textarea then you dont need to add any additional styling either.

on terminal:

npm install react-textarea-autosize

in code:

import TextareaAutosize from 'react-textarea-autosize';

// If you use CommonJS syntax:
// var TextareaAutosize = require('react-textarea-autosize').default;

React.renderComponent(
  <div>
    <TextareaAutosize />
  </div>,
  document.getElementById('element'),
);

Upvotes: 0

GijsjanB
GijsjanB

Reputation: 10044

<!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>

jsfiddle

Upvotes: 33

Dr. Hans-Peter St&#246;rr
Dr. Hans-Peter St&#246;rr

Reputation: 25978

If you don't want to shift around things while the user is typing, you could just resize it when the user leaves (blur), or maybe other appropriate events. That's what did it for me:

shrinkOnBlur(event) {
    setTimeout(function () {
        event.target.rows = 1;
        while (event.target.scrollHeight > event.target.clientHeight) {
            event.target.rows++;
        }
    }, 100);
}

Possibly you can add some space on focus (which is removed again on blur).

Upvotes: 0

MiMFa
MiMFa

Reputation: 1164

I think this answer is almost more complete and correct because it uses the rows property of the textarea:

function addLiveAutoHeight(id, maxHeight=10) {
    const tag = document.getElementById(id);
    if(!Number.isInteger(maxHeight)){
        tag.style.maxHeight = maxHeight;
        maxHeight = 999999999;
    }
    tag.rows = Math.min(maxHeight,tag.value.split("\n").length);
    document.getElementById(id).oninput = function () {
        this.rows = Math.min(maxHeight,this.value.split("\n").length);
    }
}

and to use:

addLiveAutoHeight("MY_TEXTAREA_ID");

Enjoy...

Upvotes: 0

erfanilaghi
erfanilaghi

Reputation: 278

Dynamic textArea using pure css:

if you want to use only css you can also create your element like this:

function contentTransfer(){
  document.getElementsByClassName("container")[0].innerHTML = document.getElementById("myTextArea").innerHTML;
}
.custom_textArea{
  border: 1px solid lightGray;
  padding: 7px;
  border-radius: 7px;
  outline: none;
}

.custom_textArea:focus{
  border: 1px solid darkGray;
}
<p id="myTextArea" class="custom_textArea" contenteditable="true">my text</p>
<button onclick="contentTransfer()">get content</button>
<p class="container"></p>

Upvotes: 1

hossein sedighian
hossein sedighian

Reputation: 2035

I wanna use this

window.auto_grow = async element => {
    element.style.height = "5px";
    element.style.height = (element.scrollHeight) + "px";
}

and call it

<textarea oninput="window.auto_grow(this)" onfocus="window.auto_grow(this)"></textarea>

Upvotes: 1

bafsar
bafsar

Reputation: 1108

This is a mixed JS/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";
  });
});

And this one is Mystral's comment. It's more like jquery code.

$(function() {
  $("textarea.auto-grow").on("input", function() {
    $(this).css("height", "5px")
           .css("height", $(this).prop("scrollHeight") + "px");
  });
});

CSS:

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

Html:

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

Upvotes: 0

Samuel Gfeller
Samuel Gfeller

Reputation: 1000

Improved responsive pure JS solution with @DreamTeK's second option as basis

The following also takes care of the bottom padding as well as window resize. Like this, it's a near perfect solution for me. Big thanks to him.

let textareas = document.getElementsByClassName("auto-resize-textarea");

// Loop through textareas and add event listeners as well as other needed css attributes
for (const textarea of textareas) {
    // Initially set height as otherwise the textarea is not high enough on load
    textarea.style.height = textarea.scrollHeight.toString();
    // Hide scrollbar
    textarea.style.overflowY = 'hidden';
    // Call resize function with "this" context once during initialisation as it's too high otherwise
    resizeTextarea.call(textarea);
    // Add event listener to resize textarea on input
    textarea.addEventListener('input', resizeTextarea, false);
    // Also resize textarea on window resize event binding textarea to be "this"
    window.addEventListener('resize', resizeTextarea.bind(textarea), false);
}
function resizeTextarea() {
    // Textareas have default 2px padding and if not set it returns 0px
    let padding = window.getComputedStyle(this).getPropertyValue('padding-bottom');
    // getPropertyValue('padding-bottom') returns "px" at the end it needs to be removed to be added to scrollHeight
    padding = parseInt(padding.replace('px',''));
    this.style.height = "auto";
    this.style.height = (this.scrollHeight) + "px";
}
textarea {
  width:40%;
  padding:20px 25px;
  border-radius: 20px;
}
<textarea class="auto-resize-textarea">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</textarea>
<textarea placeholder="Type, paste, cut text here..." class="auto-resize-textarea"></textarea>

Note: there is a weird issue with jsfiddle where the textarea is too high and there is too much space at the bottom, but copying and pasting this exact code to an empty HTML-file works perfectly.

There is a small issue though when a scrollbar appears on the page and the textarea shrinks and wraps the text and creates a new line. The above function does not take that into account and I made a question, but no-one seems to know a fix. If you have suggestions to resolve the issue, I would be very glad.

Upvotes: 3

Ricardo Canelas
Ricardo Canelas

Reputation: 2460

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} />;

Upvotes: 5

Max Hoffmann
Max Hoffmann

Reputation: 3047

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.

Upvotes: 19

Chris
Chris

Reputation: 2290

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>

Upvotes: 2

Johansrk
Johansrk

Reputation: 5250

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;
}

Upvotes: 0

Nikunj Bhatt
Nikunj Bhatt

Reputation: 197

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>

Upvotes: 5

Webmaster G
Webmaster G

Reputation: 532

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>

Upvotes: 7

17K
17K

Reputation: 471

Found an one liner from here;

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

Upvotes: 43

karthik_krish
karthik_krish

Reputation: 93

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);
    });

Upvotes: 2

localhostdotdev
localhostdotdev

Reputation: 1895

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)

Upvotes: 3

Divyanshu Rawat
Divyanshu Rawat

Reputation: 4721

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';
    }
  }

Upvotes: 3

Karl Zillner
Karl Zillner

Reputation: 614

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.

Upvotes: 0

Mauricio S&#225;nchez
Mauricio S&#225;nchez

Reputation: 5282

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>

Upvotes: 4

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</textarea>
<script src="https://cdnjs.cloudflare.com/ajax/libs/autosize.js/4.0.2/autosize.min.js"></script>
<script>autosize(document.querySelectorAll('#autosize'));</script>

BTW, if you are using the ACE editor, use maxLines: Infinity: Automatically adjust height to contents in Ace Cloud 9 editor

Upvotes: 13

Kim Homann
Kim Homann

Reputation: 3229

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();

Upvotes: 2

Igor Krupitsky
Igor Krupitsky

Reputation: 885

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();
}

Upvotes: 2

Related Questions