skip to Main Content

I am trying to create a <textarea> that automatically resizes based on the content inside it. However, it sometimes grows too large, larger than the content is.

I am using tailwind in the code, I am testing it in Firefox if it helps.

I have tried resizing font size. It actually helped when the font is big enough, but of course that is not a final solution. Tried few other dumb stuff, then realized that it probably isn’t the JavaScript code that is wrong and I have probably some problems in the TailwindCSS part.

There is my code:

msgBox.addEventListener('input', function() {
  this.style.height = 'auto';
  this.style.height = this.scrollHeight + 'px';
});
body {
  background: black;
}

textarea {
  background: darkblue;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">

<textarea id="msgBox" maxlength="1024" class="flex-1 px-3 py-2 h-10 text-white rounded-lg border border-black resize-none min-h-10 focus:outline-none" style="max-height: 100px; overflow-y: auto; box-sizing: border-box;" placeholder="Text here"></textarea>

I viewed the suggested similar question in the comments under this question and I think it isn’t indeed the same question since I use tailwind and my problem is most likely in some wrong usage of tailwind. In the suggested similar question isn’t any word about tailwind.

Well, I still don’t think the problem is cause by JavaScript, maybe I wrongly titled the problem.

I am adding snippet without tailwind.
I still think it is some kind of styling problem rather than wrong JavaScript code.

msgBox.addEventListener('input', function() {
  this.style.height = 'auto';
  this.style.height = this.scrollHeight + 'px';
});
body {
  background: black;
}

textarea {
  background: darkblue;
}
<textarea id="msgBox" maxlength="1024" style="max-height: 100px; overflow-y: auto; box-sizing: border-box;" placeholder="Text here"></textarea>

I still may not be clear what the problem is.
Specifying max-height of 100 px is just setting my max height of the textarea, nothing more.

My problem is that I always want the textarea’s height to be just perfect for what amount of content, or text there is.

Okay, so there are steps to reproduction (assuming you are trying the first code snippet with the TailwindCSS):

  1. Click on textarea (and notice its height)
  2. write something

Notice the height difference?
Why is it bigger when text would fit in the original height just fine??

Thing I notice when using browser debugging tools is, when I start typing, height: 64px; appears right away and I don’t think 64px was original height of the textarea.

Kinda can’t see difference when I remove any classes, even all of them as I once did, because without the TailwindCSS styles, the textarea is always two rows big in height when only one row is needed.

Okay….. I am adding gif. It is not high quality, hope you don’t mind that. I just showed you in this gif what happens when I write anything in the textarea even tho I don’t think the gif will help you in any way. I just typed there three question marks.

again, do you see the height difference after I type anything? There could fit two words under each other after I type, why when the one word could fit perfectly fine before?

2

Answers


  1. You need to set the rows attribute to 1, which tells the browser to start with one row, instead of two, so scrollHeight will get the correct height.

    msgBox.addEventListener('input', function() {
      this.style.height = 'auto';
      this.style.height = this.scrollHeight + 'px';
    });
    body {
      background: black;
    }
    
    textarea {
      background: darkblue;
    }
    <textarea id="msgBox" maxlength="1024" style="max-height: 100px; overflow-y: auto; box-sizing: border-box;" rows="1" placeholder="Text here"></textarea>
    Login or Signup to reply.
  2. the problem is you set "height" to "auto" before you get "scrollHeight". When you set height to auto, browser will calculate the box size depend on the inner strategy. For textarea, the height will be rows * lineHeight, and the default value of rows is 2. Here are 3 solutions:

    1. add rows=1 attribute on textarea.

    <textarea rows="1" id="msgBox" maxlength="1024" class="flex-1 px-3 py-2 h-10 text-white rounded-lg border border-black resize-none min-h-10 focus:outline-none" style="max-height: 100px; overflow-y: auto; box-sizing: border-box;" placeholder="Text here"></textarea>

    1. just remove this.style.height = "auto";

    2. use js to calculate the lines, then get height by lines * lineHeight + padding

    let numberOfLineBreaks = (value.match(/n/g) || []).length;
      // min-height + lines x line-height + padding + border
      let newHeight = 20 + numberOfLineBreaks * 20 + 12 + 2;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search