Wachsende Textarea
Datum: Oktober 2025
Lesedauer: 2 Minuten
Ziel
Ein Eingabefeld, das seine Höhe automatisch an den Inhalt anpasst.
Beispiel:
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 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 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.
<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.
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>
);
}