2025
Growing Textarea

Growing Textarea

Translated from German using DeepL.

Date: October 2025
Reading time: 2 minutes


Goal

An input field that automatically adjusts its height to fit the content.
Example:

chatgpt
Source: https://chat.com (opens in a new tab)

Problem

With the HTML elements and simple CSS styles available today, it is not possible to create a text field that automatically adjusts its height to the content. Neither <input> nor <textarea> automatically increase in size vertically as the content increases.

Input

input.txs
<input type="text" placeholder="Input"></input>


Textarea

Although the text area has a resize functionality by default, this is not dynamic and must be controlled manually by the user.
In both cases, the height does not adjust automatically.

textarea.txs
<textarea placeholder="Textarea"></textarea>
<textarea placeholder="Textarea" style={{resize:"none"}}></textarea>




Contenteditable

One possible solution is to use the contenteditable attribute (contentEditable in React).
This dynamically adjusts the size and is also used in ChatGPT, for example.

content-editable.txs
<span className="input" role="textbox" contentEditable></span>

ContentEditable

However, <input> (single line) or <textarea> (multiple lines) should always be used for user input.
This implementation has several disadvantages:

  • Accessibility: A contenteditable element is not a real form element. Support for screen readers and keyboard operation is limited. role=“textbox” can help, but it is no substitute for a full A11y implementation.
  • Manual implementation of standard functions: Placeholders, validation, HTML filtering for copy/paste, etc. All of this must be implemented manually.
  • Form behavior: contenteditable elements are not natively integrated into form behavior. Functions such as submitting on Enter or form serialization require additional logic.
  • Other pitfalls: Unexpected behavior can occur if you don't find out and address all the other issues.

Possible Solution

My preferred solution is a <textarea> that uses JavaScript to adjust its height (target.style.height) to the height of the actual content (target.scrollHeight).

textarea-custom.txs
export function TextareaCustom() {
    const maxHeight = 120;
 
    const handleInput = (ev) => {
        const target = ev.target;
        target.style.height = 'auto';
        if (target.scrollHeight > maxHeight) {
            target.style.height = `${maxHeight}px`;
        } else {
            target.style.height = `${target.scrollHeight}px`;
        }
    };
 
    // rows={1}         -> initial rows
    // resize:"none"    -> no user drag
    return (
        <textarea
            rows={1}
            placeholder="Custom Textarea"
            onInput={handleInput}
            style={{width:"184px", resize:"none"}}
        ></textarea>
    );
}