0

My question is in the title : How to adjust the size of a textarea automatically according to the text with React

I want to adjust my textarea height dynamically with Refs and pass it to the state but it don't work correctly.

I created a codesandbox to help you to understand what exactly I want.

https://codesandbox.io/s/ol5277rr25

In my example I take the textarea height with Ref and I pass it to the state in the onChange event but for each letter typed the height increases, it don't work correctly..

One other solution would be to split the textarea in an array when line break, and for each line break, increase the textarea height (1 line-break = 1 row). But I can not detect automatic line breaks (for line break when I press Enter no problem).. if you have ideas ?

I have already used react-autosize-textarea but I prefer do that on my own :)

Flosrn
  • 85
  • 1
  • 2
  • 9
  • How about this -- don't use 'height', use 'rows': rows={ this.state.rows} ` https://codesandbox.io/s/ny87x6pzm – Snowmonkey Feb 28 '19 at 18:33
  • Not working, for each typed letter the row increases :/ – Flosrn Feb 28 '19 at 18:40
  • 1
    Actually, this one does quite well: https://codepen.io/Libor_G/pen/eyzwOx -- I don't care for the fact that the textarea's line height is being hard-coded, but it works nicely – Snowmonkey Feb 28 '19 at 18:48
  • Thank you @Snowmonkey, it work but it's not the much optimal approach because if we change the line-height value the textarea height increase more than enough. But for the moment it's the approach which works best of all the ones I could test.. – Flosrn Feb 28 '19 at 19:50
  • If you change the lineheight, it may be worth looking in to calculating that, rather than hard-coding it: https://stackoverflow.com/questions/4392868/javascript-find-divs-line-height-not-css-property-but-actual-line-height – Snowmonkey Mar 02 '19 at 19:27

2 Answers2

2

Thats because you are getting Element.clientHeight which is CSS Height + Padding. I looked into your sandbox and you have a padding of 4px. So the clientHeight increases by 4px everytime.

The solution to this and to dynamically increase the textarea height is to use Element.scrollHeight instead of clientHeight. Thats it!

EDIT: Also set the padding to 0.

Anand Popat
  • 143
  • 8
  • 1
    Ohh sorry. I forgot to add that I set the padding to 0, here is the sandbox link https://codesandbox.io/s/k386r4r6zv – Anand Popat Feb 28 '19 at 21:06
  • Oh thank you it work !! Thank you so much I substract 8px to the height and it work perfectly with the normal padding ! :D – Flosrn Feb 28 '19 at 21:39
  • This doesn't shrink when you remove text though – mTv Aug 24 '21 at 12:07
0

You will need to set the height to auto before setting a new height value.

var autosize = document.getElementsByClassName('autosize')[0];

addEvent(autosize, ['change', 'cut', 'paste', 'keydown' ], e => resize(autosize));

function addEvent(el, types, fn) {
  if (typeof types === 'string') types = [ types ];
  types.forEach(type => el.addEventListener(type, fn));
}

function resize(ara) {
  ara.style.height = 'auto'; /* Always set to auto before resizing... */
  ara.style.height = ara.scrollHeight + 'px';
}
.container {
  width: 80%;
  margin: 0 auto;
}
.autosize {
  width: 100%;
  height : auto;
}
<div class="container">
  <textarea class="autosize"></textarea>
</div>
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132