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

ValueBehavior
trueElement is editable with rich text support (bold, italic, links via keyboard shortcuts)
plaintext-onlyElement is editable but strips all formatting. Paste operations lose rich text.
falseNot 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>
Type here. Paste strips formatting.

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 changes el.addEventListener('input', (e) => { console.log('New content:', el.textContent); }); // Read the content const text = el.textContent; // Plain text const html = el.innerHTML; // With formatting // Set the content el.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

Click to start writing your note...

Accessibility

  • Contenteditable elements are automatically focusable and receive an implicit role="textbox"
  • Screen readers announce them as editable regions
  • Add aria-label or aria-labelledby if 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