Attributo HTML contenteditable
L'attributo contenteditable specifica se il contenuto di un elemento è modificabile. Valori, gestione JavaScript e consigli sull'accessibilità.
L'attributo HTML contenteditable specifica se il contenuto di un elemento è modificabile direttamente nel browser. Quando è attivato, l'utente può fare clic all'interno dell'elemento e digitare, eliminare e formattare il testo proprio come in un elaboratore di testi — senza bisogno di <input> o <textarea>.
Poiché funziona su quasi ogni elemento, contenteditable può trasformare un <div>, un <p> o un'intera sezione in una superficie di modifica. Fa parte degli Attributi Globali, quindi è disponibile su ogni elemento HTML.
Quando usare contenteditable
contenteditable è la base della modifica in-page. Lo si trova alla base di:
- Editor di testo avanzato (le caselle "WYSIWYG" nei CMS, client di posta e moduli dei commenti). A differenza di un
<textarea>, un elemento modificabile può contenere vero HTML — testo in grassetto, link, elenchi e immagini — così l'utente vede l'output formattato mentre digita. - Modifica inline — consentire all'utente di fare clic su un'intestazione o su una cella di tabella per rinominarla direttamente, invece di aprire un modulo separato.
- UI di anteprima live e presa di note, dove l'area di modifica è il risultato visualizzato.
Scegli un <textarea> o un <input> quando hai bisogno solo di testo semplice che venga inviato con un modulo: sono veri campi di form, si validano e inviano il proprio valore automaticamente. Usa contenteditable quando hai bisogno di contenuto formattato (HTML) o vuoi che la modifica avvenga all'interno del layout di pagina esistente.
Sintassi
<tag contenteditable="true">...</tag>L'attributo accetta i seguenti valori:
| Valore | Significato |
|---|---|
true (o "") | L'elemento è modificabile. Una stringa vuota si comporta come true. |
false | L'elemento non è modificabile. |
inherit | L'elemento eredita lo stato di modificabilità dal genitore più vicino. È anche il comportamento predefinito quando l'attributo è omesso. |
plaintext-only | L'elemento è modificabile ma la formattazione rich-text è disabilitata — viene accettato solo testo semplice. Supportato dai browser moderni, ma verifica la compatibilità prima di farci affidamento. |
Esempio
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<p contenteditable="false">
This is a paragraph. It is not editable.
</p>
<p contenteditable="true">
This is a paragraph. It is editable. Try to change this text.
</p>
</body>
</html>Ereditarietà con il valore inherit
Quando non si imposta contenteditable su un elemento figlio, esso eredita lo stato di modificabilità dal genitore. Puoi rendere modificabile un'intera regione nel genitore e poi escludere un figlio specifico con contenteditable="false":
<!DOCTYPE html>
<html>
<head>
<title>contenteditable inherit example</title>
</head>
<body>
<div contenteditable="true">
<p>This paragraph inherits editing from the div, so you can change it.</p>
<p contenteditable="false">
This paragraph opts out — it is locked and cannot be edited.
</p>
<p contenteditable="inherit">
This one explicitly inherits, so it is editable again.
</p>
</div>
</body>
</html>Lettura e salvataggio del contenuto modificato con JavaScript
Un elemento contenteditable non è un campo di form, quindi il suo valore non viene inviato con un form e non esiste la proprietà value. Il contenuto si legge direttamente dall'elemento:
element.innerHTML— il contenuto modificato come HTML (mantiene grassetto, link, elenchi).element.textContent— il contenuto modificato come testo semplice (formattazione rimossa).
Per reagire alle modifiche man mano che avvengono, ascolta l'evento input, che si attiva ad ogni cambiamento:
<!DOCTYPE html>
<html>
<head>
<title>Save editable content</title>
</head>
<body>
<div id="editor" contenteditable="true">
Edit me, then reload the page.
</div>
<script>
const editor = document.getElementById("editor");
// Restore any previously saved content.
const saved = localStorage.getItem("note");
if (saved !== null) {
editor.innerHTML = saved;
}
// Save on every edit.
editor.addEventListener("input", () => {
localStorage.setItem("note", editor.innerHTML);
// In a real app you would debounce this and POST it to a server, e.g.
// fetch("/api/save", { method: "POST", body: editor.innerHTML });
});
</script>
</body>
</html>Salvare innerHTML direttamente su un server memorizza HTML grezzo. Sanifica sempre l'HTML non attendibile sul server (o con una libreria client verificata) prima di salvarlo o visualizzarlo nuovamente, per prevenire il cross-site scripting (XSS).
Accessibilità
Un elemento contenteditable semplice appare modificabile ma, a differenza di un vero campo di form, non espone alcuna semantica di campo alle tecnologie assistive — gli screen reader potrebbero non annunciarlo come qualcosa in cui l'utente può digitare. Quando costruisci un editor personalizzato, aiuta gli utenti:
- Aggiungi
role="textbox"in modo che venga annunciato come campo di testo modificabile. Aggiungiaria-multiline="true"se accetta più righe. - Aggiungi un
aria-label(o associa un<label>visibile tramitearia-labelledby) in modo che il campo abbia un nome accessibile. - Aggiungi
tabindex="0"se l'elemento non è naturalmente focalizzabile, in modo che gli utenti da tastiera possano raggiungerlo.
<div
contenteditable="true"
role="textbox"
aria-multiline="true"
aria-label="Comment"
tabindex="0"
>
Type your comment…
</div>Differenze tra browser
contenteditable è potente ma il suo comportamento non è uniforme tra i browser — questo è il motivo principale per cui le app in produzione di solito si basano su una libreria (o usano plaintext-only) anziché su contenteditable grezzo:
- Il markup del tasto Enter varia. Premere Enter può racchiudere una nuova riga in un
<div>, un<p>, o inserire un<br>, a seconda del browser. Non dare per scontata la struttura HTML generata. - L'incolla porta spesso con sé stili e tag dalla sorgente; potrebbe essere necessario intercettare l'evento
pastee ripulirlo. plaintext-onlydisabilita la formattazione rich-text ma non è supportato ovunque — verifica la funzionalità prima di farci affidamento.
Attributi correlati
spellcheck— attiva/disattiva il controllo ortografico del browser all'interno di una regione modificabile.draggable— controlla se un elemento può essere trascinato.- Attributi Globali — l'insieme completo di attributi utilizzabili su qualsiasi elemento.