contenteditable
Make any element editable by the user. Supports rich text or plaintext-only modes for inline editing experiences.
Overview
The contenteditable attribute makes any HTML element editable by the user. It turns the element into a free-form text input without needing a <textarea> or <input>.
This is the foundation for inline editing, note-taking interfaces, and rich text editors.
Applies to: Any HTML element
Values
| Value | Behavior |
|---|---|
true | Element is editable with rich text support (bold, italic, links via keyboard shortcuts) |
plaintext-only | Element is editable but strips all formatting. Paste operations lose rich text. |
false | Not editable (the default) |
<!-- Make a paragraph editable --><p contenteditable="true">Click to edit this text.</p> <!-- Editable heading --><h2 contenteditable="true">Editable Title</h2>
Click to edit this text. Try typing, selecting, and using keyboard shortcuts.
Plaintext-Only Mode
The plaintext-only value is ideal when you want editable text without formatting. Pasted content is stripped of all HTML, and keyboard shortcuts like Ctrl+B have no effect.
<!-- Plaintext only: strips formatting on paste --><div contenteditable="plaintext-only"> Type here. Pasted content loses all formatting.</div>
Rich Text Editing
With contenteditable="true", the browser provides built-in formatting:
- Ctrl+B / Cmd+B for bold
- Ctrl+I / Cmd+I for italic
- Ctrl+U / Cmd+U for underline
<!-- Editable blockquote --><blockquote contenteditable="true"> Click here to edit this quote. You can use <strong>bold</strong> and <em>italic</em> formatting.</blockquote>
JavaScript API
Listen for input events to react to changes, and read content via textContent or innerHTML.
const el = document.querySelector('[contenteditable]'); // Fires when content changesel.addEventListener('input', (e) => { console.log('New content:', el.textContent);}); // Read the contentconst text = el.textContent; // Plain textconst html = el.innerHTML; // With formatting // Set the contentel.textContent = 'New plain text';el.innerHTML = '<strong>New</strong> formatted text';
Practical Example
An editable note card with a plaintext body:
<article> <h3 contenteditable="true">Note Title</h3> <div contenteditable="plaintext-only"> Click to start writing your note... </div></article>
Note Title
Accessibility
- Contenteditable elements are automatically focusable and receive an implicit
role="textbox" - Screen readers announce them as editable regions
- Add
aria-labeloraria-labelledbyif the editable region has no visible label - Use
aria-multiline="true"for multi-line editable regions
Limitations
- No form participation: contenteditable elements are not form controls. Their content is not included in form submissions. Use a hidden
<input>or JavaScript to bridge the gap. - No validation: Unlike
<input>and<textarea>, there is no built-in constraint validation. - Browser differences: Rich text editing behavior varies across browsers, especially for line breaks and formatting commands.
See Also
<textarea>for standard multi-line text inputdata-growfor auto-expanding textareas