Why textareas can’t grow?

Textareas are a basic and and an important element in any website UI. You might need textareas for a comment section, chat box, etc.

However, textareas have one small problem that you can’t seem to find an answer, that is textareas won’t automatically grow in height, as you would need them to be in a modern UI website.

Textareas have a fixed height, and if the text overflows this height, then the usual way is for textareas to have scrollbars.

This is somewhat of an anti-pattern in today’s websites. No one wants to have scrollbars in their textareas, users and developers want the textareas to grow and make all the user input visible at all times.

I remember struggling to create a growing textarea five years back when I was trying to develop a website. Back then the solution has been to automatically increase the height property of the textarea style by using jQuery.

Since I don’t use jQuery anymore, and I don’t want to use jQuery just to grow a textarea, I searched the internet while I was trying to develop a textarea that grows for Tuti. An online flashcard creator that I’m building for fun.

If you googled this question, you will see that so many questions have been asked and people have come up with different solutions of their own from time to time, depending on the tech and CSS available during their time (like I used jQuery five years ago to solve the same problem)

The latest and the most popular answer available Google and Stackoverflow points to this blog post on CSS-Tricks, which uses some CSS magic and one line of Javascript to create an automatically growing textarea.

Yes, this seems great, and the demo also works fine. However, for some reason when I try to mix the solution with Vue or AlpineJs which I’m currently using for another small web app, there is an annoying delay between the keypress and your text appearing on screen.

It won’t have much of an effect on someone who types slowly, but for somewhat who is trying relatively fast it tends to be super annoying.

I tried using different events, (keyup, keydown, onInput) but nothing seems to get rid of me this annoying delay that I’m getting.

This is not to say that the answer on CSS-Tricks is bad, but it is not the right solution for me when I combine that with a javascript framework. Maybe it has to do with something that has to do with Vue or other DOM manipulating frameworks.

What others are doing

So I decided to check what are the solutions that are being used by popular websites, especially Twitter and Facebook. Since an auto-growing textarea plays a central role in their UI. Posting content and comments on Facebook, and writing a new Tweet on Twitter.

Upon inspecting the website’s code, it seems both services are using a content-editable div, and are not depending on a textarea at all.

So I thought of doing the same, and here’s the solution that I came up for my web app for the time being.

Step 1

Create a div with content editable being true.

<div id="growingTextarea" placeholder="some placeholder text" contenteditable="true"></div>

Step 2

Textareas have placeholders, but you can’t simply add a placeholder property to a content editable div. But you can add a placeholder property to the div and make it visible to the user with the help of some CSS.

[contenteditable=true]:empty:before{
  content: attr(placeholder);
  @apply text-gray-400 text-lg; /* the @apply notations are to import the styles via tailwindCss */
  pointer-events: none;
  display: block; /* For Firefox */
}

Step 3

Retrieve the content of the div with the help of Javascript.

document.getElementById('growingTextarea').innerText

Result

See the Pen Auto growing TextArea by Rukshan Ranatunge (@rukshn) on CodePen.

Conclusion

It’s funny how even with so many web apps depending on textareas that are auto-growing, still there is no css only, standard method to create a textarea that is automatically increasing in size, without having to depend on CSS or Javascript hacks.

Maybe content editable might have their own issues, but it’s something that currently works for me solving my problem.

If you know any alternative solutions (which I’m sure there are many) feel free to let me know on Twitter via https://twitter.com/justruky

Leave a Comment