LearnNative Rich-Text Editing with the contenteditable Attribute

Matt West
writes on November 1, 2013

One of the lesser-known HTML attributes is contenteditable. This attribute allows you to turn a standard read-only HTML element into an interactive, rich-text editor.

When Tim Berners-Lee built the first web browser in 1990, he created modes for both browsing and editing HTML documents. However as the web grew, browsers transitioned to a more read-only state. The contenteditable attribute and associated element properties bring native content editing back to the browser.

Tim Berners-Lee's Web Browser

Tim Berners-Lee’s Original Web Browser (Source: http://info.cern.ch/NextBrowser.html)

In this blog post you are going to learn how to use the contenteditable attribute to allow users to edit page content directly within their browser. You’ll also be taking a look at the properties that allow you to manipulate an element’s editable state using JavaScript.

The contenteditable Attribute

contenteditable-html

You can make an element editable by adding the contenteditable attribute in your markup. This attribute has three possible values: true, false, and inherit. Specifying inherit will make the element editable if it’s immediate parent is editable.

<div id="editor" contenteditable="true">
  ...
</div>

See the Demo View on CodePen


Note: Editable elements are included in the tab order and can therefore be focussed using the tab key. This makes them accessible to users that might not be able to use a mouse. The tabindex attribute can be used to specify where in the tab order the editable element should fall.


Making Elements Editable in JavaScript

contenteditable-js

As well as the contenteditable HTML attribute it is also possible to make an element editable using JavaScript. This involves two element properties:

  • isContentEditable – This property will return true if the element is editable and false if it is not.
  • contentEditable – This property can be used to set the editable status of an element. Supported values are the same as those used for the contenteditable attribute: true, false, and inherit.
var editor = document.getElementById('editor');
editor.isContentEditable;
editor.contentEditable = true;

Lets take a look at an example of how you could use a button to toggle an element’s editable state.

<button id="editorBtn" type="button">Enable Editing</button>
<div id="editor">
  ...
</div>

Here you’ve created simple <button> and <div> elements. Notice that the <div> doesn’t have a contenteditable attribute.

var editorBtn = document.getElementById('editorBtn');
var element = document.getElementById('editor');

editorBtn.addEventListener('click', function(e) {
  e.preventDefault();

  if (element.isContentEditable) {
    // Disable Editing
    element.contentEditable = 'false';
    editorBtn.innerHTML = 'Enable Editing';

    // You could save any changes here.
  } else {
    element.contentEditable = 'true';
    editorBtn.innerHTML = 'Disable Editing';
  }
});

In this JavaScript code you start by creating two variables that represent the <button> and <div> elements on the page. You then attach an event listener to the editorBtn that will be fired when the user clicks the button. Inside the callback function of this event listener you examine the <div> element’s isContentEditable property to determine whether the element is currently editable. If it is, you disable editing by setting the element’s contentEditable property to false, and update the button text to Enable Editing. If the element is not editable you first enable editing and then change the button text to Disable Editing.

See the Demo View on CodePen

Making an Entire Page Editable

If you’d like to make an entire web page editable you can use the designMode property of the document object. Setting this property to 'on' will enable editing. This also works on documents within iframes.

document.designMode = 'on';

Try turning on designMode for this page using your browser’s dev tools. Once enabled you should be able to edit all of the page content.

If you’re not familiar with using your browser’s dev tools, here’s some steps to get you going.

  • Open up your browser’s dev tools. (Right-click anywhere on the page and select ‘Inspect Element’)
  • Switch to the Console tab.
  • Type the following into the console and press enter: document.designMode = 'on';

Browser Support for contenteditable

Support for contenteditable is very good. Internet Explorer was the first browser to implement this technology, way back in IE 5.5 (circa 2000). Since then, contenteditable has been standardized by the WHATWG.

IE Firefox Chrome Safari Opera
5.5+ 3.5+ 4.0+ 3.1+ 9.0+

Source: http://caniuse.com/#feat=contenteditable

Final Thoughts

Enabling the ability to simply click an element and make an update enables a really enjoyable editing experience for the user. The contenteditable attribute makes implementing this interaction effortless.

You could enable this same behaviour by cleverly swapping in an <input> or <textarea> when an element is clicked. This is in fact the way that a number of websites still handle inline editing. The problem with this approach is that it involves writing a load of JavaScript to switch in the new <input> or <textarea>, and CSS to match it’s styling to the original element. Using contenteditable solves both of these issues.

How do you see yourself using contenteditable in your projects? Share your thoughts in the comments below.

7 Responses to “Native Rich-Text Editing with the contenteditable Attribute”

  1. Charles Robertson on January 31, 2017 at 9:41 am said:

    Is it possible to turn off contenteditable in HTML e-mails?

    When I send an e-mail from iOS6+ e-mail app from an iOS App [which I am developing], I cannot prevent the recipient from deleting text in my HTML e-mail layout.
    Like section titles in DIVs, inside table cells.

    Any ideas?

    contenteditable=’false’ does not seem to work?

  2. es, sure. But I strongly recommend **not to use pure contenteditable** for production sites. It is a great feature for prototyping, which makes it possible to quickly see how your web page will be rendered depending on its content. With some tricks it is also handy to use contenteditable as a “clipboard catcher”. But it should not be used as a production ready WYSIWYG editor. It’s too buggy and it produces a really crappy HTML with font and span tags which, additionally, does not work cross browser.

    What do I use as a WYSIWYG editor?

    You’ve got two ways:

    1. Create your own WYSIWYG editor based on contenteditable. But don’t go this way if you don’t have few months for the task, good knowledge about JS and DOM and very (I mean… really *very*) limited needs (basically – plain text + bold, italic). In other cases you’ll end up with a buggy editor producing awful HTML.
    2. Use one of the existing editors (I’m a core developer of one of them, so I won’t say which :P). But this way is still tricky. Since it is theoretically simple to create your own WYSIWYG editor, many try and many fail. Good looking UI and “just 10kb of JS” is all such projects can offer, because it’s too hard to fix contenteditable’s bugs. So… make sure you’re making a wise choice.

  3. I used https://github.com/micmmakarov/contenteditable gem with my rails app to make the content editable

  4. ContentEditable is buggy on iOS 6. Such a bummer.

  5. Contenteditable was introduced 13 years ago in IE5.5, then copied by other browsers vendors and since then… nothing has happened. There’s very little effort put into improving contenteditable implementations, so besides small bug fixes (harder bugs don’t get any attention) I can name only one thing which was more or less standardised and this is Selection and Range APIs. In fact, in case of selection it is **only** API – behaviour is very different in **every** engine. This is very similar, or even worse, than the state of the Web 13 years ago. Some more details: http://stackoverflow.com/questions/16074358/content-editable-text-editors/16085789#16085789

    Ok, so contenteditable is broken. Does it mean that it should die?

    Without contenteditable it would be extremely hard to create WYSIWYG editors for the Web and impossible to create so called “inline editors” (e.g. http://ckeditor.com/demo#inline). So I hope it will stay with us.

    So can I use contenteditable?

    Yes, sure. But I strongly recommend **not to use pure contenteditable** for production sites. It is a great feature for prototyping, which makes it possible to quickly see how your web page will be rendered depending on its content. With some tricks it is also handy to use contenteditable as a “clipboard catcher”. But it should not be used as a production ready WYSIWYG editor. It’s too buggy and it produces a really crappy HTML with font and span tags which, additionally, does not work cross browser.

    What do I use as a WYSIWYG editor?

    You’ve got two ways:

    1. Create your own WYSIWYG editor based on contenteditable. But don’t go this way if you don’t have few months for the task, good knowledge about JS and DOM and very (I mean… really *very*) limited needs (basically – plain text + bold, italic). In other cases you’ll end up with a buggy editor producing awful HTML.
    2. Use one of the existing editors (I’m a core developer of one of them, so I won’t say which :P). But this way is still tricky. Since it is theoretically simple to create your own WYSIWYG editor, many try and many fail. Good looking UI and “just 10kb of JS” is all such projects can offer, because it’s too hard to fix contenteditable’s bugs. So… make sure you’re making a wise choice.

Leave a Reply

You must be logged in to post a comment.

Want to learn more about Javascript?

Learn how to use JavaScript to add interactivity to websites.

Learn more