Transformar qualquer elemento em editável com contenteditable="true" sempre trouxe um efeito colateral incômodo: colar um texto copiado de um site ou de um editor traz junto negrito, links, cores e toda a formatação original, além de permitir que o usuário aplique Ctrl+B, Ctrl+I e outros atalhos de rich text dentro de um campo que deveria ser texto puro. O valor plaintext-only do atributo contenteditable resolve isso nativamente: o elemento continua editável, mas qualquer formatação é descartada, tanto na digitação quanto na colagem.
O jeito antigo
<div id="campo" contenteditable="true">
Escreva um comentário...
</div>
Com contenteditable="true", colar um trecho de texto de uma página qualquer traz junto tags como <b>, <a> e estilos inline. Para evitar isso, era comum interceptar o evento paste e extrair só o texto na mão:
const campo = document.getElementById('campo');
campo.addEventListener('paste', (e) => {
e.preventDefault();
const texto = e.clipboardData.getData('text/plain');
document.execCommand('insertText', false, texto);
});
Além de depender do execCommand, já obsoleto, essa abordagem não impede que o usuário aplique negrito ou itálico digitando atalhos de teclado diretamente no campo.
Como funciona o plaintext-only
Basta usar a string plaintext-only como valor do atributo, em vez de true:
<div id="campo" contenteditable="plaintext-only">
Escreva um comentário...
</div>
O elemento continua editável normalmente, mas o navegador remove qualquer marcação ao colar conteúdo, mantendo apenas o texto puro (incluindo quebras de linha). Atalhos como Ctrl+B ou Ctrl+I deixam de aplicar formatação, já que não existe mais nenhuma formatação possível dentro do elemento.
Lendo o valor via JavaScript
A propriedade contentEditable do elemento reflete o novo valor, e a propriedade somente leitura isContentEditable continua retornando true para os três modos (true, plaintext-only e o herdado inherit):
const campo = document.getElementById('campo');
console.log(campo.contentEditable); // "plaintext-only"
console.log(campo.isContentEditable); // true
Combinando com um placeholder via CSS
Como o elemento não é um <input> ou <textarea>, não existe atributo placeholder nativo, mas dá para simular um com :empty e um pseudo-elemento:
[contenteditable="plaintext-only"]:empty::before {
content: attr(data-placeholder);
color: #888;
pointer-events: none;
}
<div contenteditable="plaintext-only" data-placeholder="Escreva um comentário..."></div>
Quando usar
- Campos de comentário, bio ou legenda onde formatação rica não faz sentido, mas um
<textarea>de linha única não é flexível o suficiente. - Editores de código simples ou campos de busca com múltiplas linhas dentro de uma interface mais rica.
- Qualquer lugar que hoje usa
contenteditable="true"só para ter um campo editável, mas sanitiza o conteúdo colado na mão. - Substituir a combinação de
contenteditable="true"mais um filtro manual de HTML colado, eliminando uma fonte comum de bugs de sanitização.
Cuidados
Mesmo em modo texto puro, o elemento ainda aceita quebras de linha, então o conteúdo final pode ter múltiplas linhas — se o objetivo é um campo de uma linha só, ainda é preciso interceptar a tecla Enter manualmente. Vale lembrar também que, assim como contenteditable="true", o elemento não participa de formulários automaticamente: o valor precisa ser lido via JavaScript (por exemplo, com textContent) antes do envio.
Compatibilidade
O suporte já existe nos três motores principais (Chromium, Firefox e Safari), tornando o recurso seguro para uso em produção na maioria dos projetos atuais.
Conclusão
O contenteditable="plaintext-only" resolve um problema comum — campo editável sem formatação rica — sem exigir sanitização manual de HTML colado nem depender do execCommand, deixando o navegador cuidar de manter o conteúdo sempre como texto puro.
0 Comentário
Deixe seu Comentário!
Dúvida, sugestão ou só um "valeu!" — tudo é bem-vindo por aqui.