L'attribut contenteditable
en HTML permet de rendre des éléments éditables directement dans le navigateur, en quelque sorte un super-textarea qui permet la mise en forme dans tout élément HTML parce qu'on peut y placer ce qu'on veut... Ce qui est justement le problème de sa valeur par défaut true
: cette totale liberté permet l'insertion de balises <script>
, ce qui peut créer des failles de sécurité et des comportements indésirables.
➡️ C'est là qu'intervient contenteditable="plaintext-only"
, une valeur moins connue - car récente - mais extrêmement utile, car contrairement à contenteditable="true"
ou contenteditable
qui accepte tout code HTML, contenteditable="plaintext-only"
esquive automatiquement tout formatage et ne conserve que le texte brut.
Avec contenteditable="true"
ou contenteditable
On obtient le comportement par défaut :
- Accepte le code HTML collé (gras, italique, liens, etc.)
- Y compris mise en gras ou italique avec les raccourcis Ctrl+B/Ctrl+I
- Peut introduire des styles indésirables
- Risque de failles XSS si le contenu n'est pas vérifié
Avec contenteditable="plaintext-only"
🆕
- Supprime automatiquement tout formatage HTML
- Sécurité (relative) contre l'injection de code
- Comportement plus prévisible et cohérent
- Idéal pour les champs de saisie simple
Cas d'usage pratiques
Champ de titre ou nom, dans un CMS, enregistré ensuite en asynchrone par JavaScript / fetch.
<h1 contenteditable="plaintext-only" class="editable-title">
Cliquez pour modifier le titre
</h1>
Zone de commentaire :
<div contenteditable="plaintext-only" class="comment-input" placeholder="Votre commentaire...">
</div>
Étiquettes ou tags :
<span contenteditable="plaintext-only" class="tag">
Tag modifiable
</span>
Exemple interactif complet pour comparer
Gestion en JavaScript
Pour récupérer le contenu, avec plaintext-only
, les propriétés textContent
et innerHTML
donnent le même résultat.
const element = document.querySelector('[contenteditable="plaintext-only"]');
const content = element.textContent; // Recommandé
const htmlContent = element.innerHTML; // Sera identique à textContent
Compatibilité navigateurs
contenteditable="plaintext-only"
est bien supporté par les navigateurs actuels, pour plus de détails consultez le tableau de support Caniuse.
Sécurité et validation côté serveur
Même avec plaintext-only
, il reste obligatoire de toujours valider ce que vous recevez côté serveur car rien n'empêchera quelqu'un d'aller vite désactiver cet attribut ou modifier son comportement, voire de forger une simple requête HTTP pour passer outre. Par exemple en PHP on peut prévoir :
$userInput = trim($_POST['content']);
$cleanInput = htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
Limitations à connaître
- Les
<br>
sont convertis en retours à la ligne simples - Il y a perte des entités HTML :
&
devient&
- Pas de formatage préservé donc impossible de maintenir des espaces multiples ou de la mise en forme
Commentaires
Bonjour, intéressant.
Petite coquille, placeholder n'est pas un attribut valide pour la balise div.