The Road to HTML 5: contentEditable
Welcome back to my semi-regular column, "The Road to HTML 5," where I'll try to explain some of the new elements, attributes, and other features in the upcoming HTML 5 specification.
The feature of the day is
contentEditable, by which I mean client-side in-browser "rich text" editing. All major browsers support this now, including Firefox 3, Safari 3, Opera 9, Google Chrome, and Internet Explorer (since 5.5). Of course, the devil is in the details.
In this article:
- What is
- How does it work?
- A brief and extremely biased timeline of standardization
- Further reading
There are really two attributes involved,
designMode attribute governs the entire document (i.e. it makes the entire document editable, like a dedicated HTML editor). The
contentEditable attribute governs just the element on which it appears, and that element's children -- like a rich text editor control within a page. In fact, that was the original use case: enabling web developers to build rich text editors. There are now a variety of such editors available under various licenses.
Both of these attributes,
contentEditable, were originally designed and implemented by Microsoft in Windows Internet Explorer (5.5, to be exact). There was some superficial documentation on how to use them (so developers could develop rich text editors), but little thought of interoperability. So, no details on all the nitty gritty details of exactly what markup is generated when you press ENTER right here, or what the DOM looks like as you backspace your way through a start tag. Much of this sort of information was later reverse-engineered, and cross-browser support for basic operations is actually quite good. (Browsers still vary widely on the details.) The
contentEditable attributes, and the APIs that drive rich text editors, are implemented in all major browsers, including Firefox, Opera, Safari, Google Chrome, and of course Internet Explorer.
How does it work?
Mark Finkle wrote a nice high-level summary of
designMode, and later added a post about
contentEditable once it appeared in the Firefox 3 alphas. (That was back in 2007.) Quoting Mark:
Mozilla has a rich text editing system (called Midas) and an API similar to Internet Explorer's. Mozilla, like Internet Explorer, supports the ability to make an entire document editable by setting the designMode property of the document object. Once in design mode, the document can be manipulated using various DHTML commands.
... Firefox 3 is expanding its rich WYSIWYG editing capabilities by adding support for the contentEditable attribute. Setting contentEditable to "true" allows you to make parts of a document editable. ...
The API for interacting with the document is:
- Executes the given command.
- Determines whether the given command can be executed on the document in its current state.
- Determines whether the current selection is in an indetermined state.
- Determines whether the given command has been executed on the current selection.
- Determines the current value of the document, range, or current selection for the given command.
Once you have an editable document (
designMode) or element (
contentEditable), you use this set of API calls to issue "commands" on the editable region, and to query the current state of the region. Commands are things like "bold," "italic," "underline," "create a link," "change foreground color," and so on -- all the commands you would expect from a rich text editor. Here's a test page with 36 commands.
In other words, "supporting the
contentEditable attribute" is really just the tip of the iceberg. The real compatibility story is written in the commands which are passed to the
document.execCommand() function. So which browsers support which commands?
- Internet Explorer commands
- Mozilla Firefox commands
- Command APIs in HTML 5
- QuirksMode.org comparison chart
As you can see from Peter's chart, basic stuff like bold, italic, creating links, and changing colors is well-supported across browsers. After that, the compatibility story gets hairy.
A brief and extremely biased timeline of standardization
Reverse-engineering and standardizing
contentEditable and its associated APIs was one of the original goals of the WHAT working group, as part of (what at the time was called) "Web Applications 1.0" and is now known as "HTML 5."
- July 2000. Microsoft releases Internet Explorer 5.5, with support for
contentEditable. Other than some sparse documentation on MSDN, no further details were given.
- November 2004. Ian Hickson: [whatwg] Re: several messages. "One set of the ideas that was brought up in this forum was the ability to extend <textarea> to support syntax highlighting, or WYSIWYG editing of BB code markup, or just the ability to do rich text editing of any kind. Having considered all the suggestions, the only thing I could really see as being realistic would be to do something similar to (and ideally compatible with) IE's 'contentEditable' and 'designMode' attributes."
- April 2005. Olav Junker Kjær: "I have been thinking about HTML editing, which I think is a critical feature."
- July 2005. Anne van Kesteren: begins to reverse-engineer Microsoft's
- July 2005. Anne van Kesteren: [whatwg] [html5] contenteditable specification. The first message points to annevankesteren.nl/projects/whatwg/spec, while (somewhat surprisingly) still exists. An unfinished but fascinating piece of reverse engineering. (Most of this is now merged into the HTML 5 spec, in the Command APIs section.)
- July 2005. Anne van Kesteren: [whatwg] [html5] contenteditable specification (again)
- July 2005. Matthew Raymond: [whatwg] [WF2] Readonly and default pseudoclass matching. Discussion of how
contentEditableinteracts with proposed (and now standardized) pseudo-classes like
- August 2005. dolphinling: [whatwg] What exactly is contentEditable for?. Other than the obvious answer, "rich text editing," the discussion focused on how modified content is/could be/should be submitted to the server, and whether it could be implemented without scripting.
- September 2005. Ian Hickson: [whatwg] Status update. "Web Apps 1, a.k.a. 'HTML5'. Still very much work in progress. ... The main things that need fleshing out are: (1) contentEditable: at least to a state comparable to WinIE, although we might want to add some of the new features being requested on this list like declarative association with a form."
- September 2005. Matthew Raymond: [whatwg] Re: Simple template-based editing. Discussion of a (never-implemented)
- June 2006. Lachlan Hunt: [whatwg] Spellchecking proposal #2. Discussion of how
contentEditableinteracts with the
spellcheckattribute. See also: Ian Hickson's feedback, with examples.
- July 2006. Anne van Kesteren: [whatwg] contenteditable="" needs fixing. (This later led to these test cases.)
- January 2007. Simon Pieters: [whatwg] contenteditable, <em> and <strong>
- January 2007. Anne van Kesteren: [whatwg] contenteditable="" values and isContentEditable
- February 2007. Ian Hickson: "I have added it to the now-written designMode section."
- April 2007. David Hyatt: "The use case of being able to drop images into a contenteditable region and have them show up as <img /> elements at the appropriate place and then get automatically uploaded somewhere is a really compelling one." See also: Ian Hickson's feedback, 19 months later.
- November 2008. Ian Hickson: "contentEditable is being made more consistent, but there's still no non-scripted solution, since nobody can agree on what elements to allow."
- December 2008. Ian Hickson: [whatwg] <input placeholder="">. Discussion of whether the
placeholderattribute should also apply to
designModedocuments in an
The original use case for
contentEditable -- building rich text editors -- is alive and well on the web. Cross-browser compatibility can be charitably described as "evolving," but we are long past the point where "only IE can do that fancy rich-text stuff." Standardization through the WHATWG has shaken out numerous interoperability bugs and led to thoughtful consideration of a wide variety of edge cases. Most of these benefits had to be realized through reverse engineering, rather than cooperation, but the work has been done and the web is better for it.
- Edit-in-place with contentEditable property. Up-to-date, cross-browser.
- Rich HTML editing in the browser: part 1. A basic tutorial. Up-to-date, cross-browser.
- Rich HTML editing in the browser: part 2. More advanced. Up-to-date, cross-browser.
- Finding cursor position in a contentEditable div. Up-to-date, cross-browser.
- contentEditable attribute on MSDN partially documents Internet Explorer's implementation. A bit out of date (see comments). Microsoft-only.
- Opera's test cases for
execCommandcompatibility. A bit out of date. Covers older browsers only, no public betas, no Firefox 3, no Google Chrome.
- The bane and choice of Rich Text Editors.