Signatur
Beschreibung
Die Eigenschaft contentEditable spiegelt das HTML-Attribut contenteditable wider. Ist sie auf "true" gesetzt, kann der Benutzer den Inhalt des Elements direkt im Browser verändern: Text eintippen, löschen, einfügen und formatieren. So lassen sich Rich-Text-Editoren, direkt bearbeitbare Titel, Notizfelder oder Tabellenzellen ohne <input> oder <textarea> bauen.
Gültige Werte sind:
"true": Das Element ist bearbeitbar, auch mit Formatierung (HTML)."false": Das Element ist nicht bearbeitbar, selbst wenn ein übergeordnetes Element bearbeitbar ist."plaintext-only": Nur reiner Text ist erlaubt. Formatierungen und eingefügtes HTML werden verworfen."inherit": Der Zustand wird vom Elternelement geerbt (Standardwert, wenn das Attribut fehlt).
Die Eigenschaft ist ein String und kein Boolean. Wer nur prüfen will, ob ein Element tatsächlich bearbeitbar ist (also auch durch Vererbung), nimmt besser die schreibgeschützte Eigenschaft isContentEditable. Wird ein ungültiger Wert zugewiesen, wirft der Browser einen SyntaxError (DOMException).
Änderungen an bearbeitbaren Elementen lassen sich über die Events beforeinput und input verfolgen. Den bearbeiteten Inhalt liest man danach über textContent, innerText oder innerHTML aus.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value | "true" | "false" | "plaintext-only" | "inherit" | "inherit" | Nur beim Setzen: neuer Bearbeitungszustand. Groß- und Kleinschreibung spielt keine Rolle. Andere Werte lösen einen SyntaxError aus. |
Rückgabewert
"true", "false", "plaintext-only" oder "inherit". Ist kein Attribut gesetzt, wird "inherit" geliefert.Beispiele
Bearbeitungsmodus per Button umschalten
const note = document.querySelector('#note');
const button = document.querySelector('#toggle');
button.addEventListener('click', () => {
const editing = note.contentEditable === 'true';
note.contentEditable = editing ? 'false' : 'true';
button.textContent = editing ? 'Bearbeiten' : 'Fertig';
if (!editing) note.focus();
console.log('Zustand:', note.contentEditable);
});
Nur Klartext erlauben und Änderungen speichern
const title = document.querySelector('h1.page-title');
// Formatierungen und eingefügtes HTML werden verworfen
title.contentEditable = 'plaintext-only';
title.addEventListener('input', () => {
localStorage.setItem('pageTitle', title.textContent.trim());
});
// Enter beendet die Bearbeitung statt einen Zeilenumbruch einzufügen
title.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
event.preventDefault();
title.blur();
}
});
String-Wert vs. isContentEditable und ungültige Werte
const wrapper = document.createElement('div');
const child = document.createElement('span');
wrapper.appendChild(child);
document.body.appendChild(wrapper);
wrapper.contentEditable = 'true';
console.log(child.contentEditable); // Attribut nicht gesetzt
console.log(child.isContentEditable); // tatsächlich bearbeitbar
try {
child.contentEditable = true; // Boolean wird zu "true" – funktioniert
child.contentEditable = 'yes'; // ungültig
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
- String statt Boolean:
if (el.contentEditable)ist immer wahr, weil auch"false"ein nicht-leerer String ist. Vergleiche mit=== 'true'oder nutzeisContentEditable. - Sicherheit (XSS): Wer bearbeiteten Inhalt über
innerHTMLausliest und speichert oder später wieder ausgibt, übernimmt womöglich eingefügtes Fremd-HTML. Das HTML also vor dem Speichern bereinigen (z. B. mit DOMPurify) oder"plaintext-only"undtextContentverwenden. - Uneinheitliches Markup: Browser erzeugen beim Tippen und Einfügen unterschiedliches HTML (
<div>,<br>,<p>).document.execCommand()ist veraltet. Für ernsthafte Editoren empfehlen sichbeforeinputund die Selection-API oder eine erprobte Bibliothek. - Kompatibilität:
"true","false"und"inherit"werden überall unterstützt."plaintext-only"ist erst seit 2025 in allen großen Browsern verfügbar (Firefox ab Version 136). Bei älteren Versionen gibt es einenSyntaxError, deshalb eine Rückfallebene mittry/catcheinbauen. - Barrierefreiheit: Bearbeitbare Elemente mit
role="textbox"und einemaria-labelversehen, damit Screenreader sie richtig ansagen.