2025
Wachsende Textarea

Wachsende Textarea

Datum: Oktober 2025
Lesedauer: 2 Minuten


Ziel

Ein Eingabefeld, das seine Höhe automatisch an den Inhalt anpasst.
Beispiel:

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

Problem

Mit den heute verfügbaren HTML-Elementen und einfachen CSS-Stilen ist es nicht möglich, ein Textfeld zu erstellen, das sich automatisch in der Höhe an den Inhalt anpasst. Weder <input> noch <textarea> vergrössern sich bei zunehmendem Inhalt automatisch in der Vertikalen.

Input

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


Textarea

Die Textarea verfügt zwar standardmässig über eine resize-Funktion, diese ist jedoch nicht dynamisch, sondern muss manuell vom Nutzer gesteuert werden.
In beiden Fällen passt sich also die Höhe nicht von selbst an.

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




Contenteditable

Eine mögliche Lösung ist die Verwendung des contenteditable-Attributs (contentEditable in React).
Dieses passt die Grösse dynamisch an und wird z.B. auch in ChatGPT eingesetzt.

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

ContentEditable

Allerdings sollten für Benutzereingaben immer <input> (einzeilig) oder <textarea> (mehrzeilig) verwendet werden.
Eine solche Implementierung bringt einige Nachteile mit sich:

  • Accessibility: Ein contenteditable-Element ist kein echtes Formularelement. Die Unterstützung für Screenreader und Tastaturbedienung ist eingeschränkt. role="textbox" kann helfen, ersetzt aber keine vollwertige A11y-Implementierung.
  • Manuelle Umsetzung von Standardfunktionen: Placeholder, Validierung, HTML-Filterung bei Copy/Paste, ... all das muss manuell implementiert werden.
  • Formularverhalten: contenteditable-Elemente sind nicht nativ in das Formularverhalten integriert. Funktionen wie das Absenden auf Enter oder die Formularserialisierung erfordern zusätzliche Logik.
  • Weitere Fallstricke: Unerwartetem Verhalten kann auftreten, wenn man nicht alle weiteren Punkte herausfindet und behandelt.

Lösungsvariante

Meine präferierte Lösung ist eine <textarea>, welche ihre Höhe (target.style.height) mit JavaScript an die Höhe des tatsächlichen Inhalts (target.scrollHeight) angleicht.

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