The contenteditable attribute

by .

For some time now, we’ve been using various technologies to edit and store text within a web browser. Now with the contenteditable attribute, things have got a whole lot easier. In this article, I’ll tell you what this attribute is for, how it works, and how we can take things further.

The Basics

First, let’s check out the spec:

The contenteditable attribute is an enumerated attribute whose keywords are the empty string, true, and false. The empty string and the true keyword map to the true state. The false keyword maps to the false state. In addition, there is a third state, the inherit state, which is the missing value default (and the invalid value default).

The contenteditable attribute was mainly intended for providing an in-browser rich-text or WYSIWYG experience. You’ve likely seen this sort of thing in blog-based authoring tools like Symphony or sites like Flickr where you can begin editing page content simply by clicking in a given area.

As mentioned above, contenteditable has three possible states:

contenteditable="" or contenteditable="true"
Indicates that the element is editable.
contenteditable="false"
Indicates that the element is not editable.
contenteditable="inherit"
Indicates that the element is editable if its immediate parent element is editable. This is the default value.

When you add contenteditable to an element, the browser will make that element editable. In addition, any children of that element will also become editable unless the child elements are explicitly contenteditable="false".

Code Example

Here’s some example code to get us started:

<div id="example-one" contenteditable="true">
<style scoped>
  #example-one { margin-bottom: 10px; }
  [contenteditable="true"] { padding: 10px; outline: 2px dashed #CCC; }
  [contenteditable="true"]:hover { outline: 2px dashed #0090D2; }
</style>
<p>Everything contained within this div is editable in browsers that support <code>HTML5</code>. Go on, give it a try: click it and start typing.</p>
</div>
    
Putting it together

Live examples

Here are two basic-but-live examples showing what you can do with contenteditable.

Example One

Everything contained within this div is editable in browsers that support HTML5. Go on, give it a try: click it and start typing.

Live text editing

I’ve used CSS to create an obvious visual cue that this area of text is different from the rest. Note that I’ve future-proofed this with <style scoped>, which I covered in my previous article.

Example Two

Chris Coyier of CSS-Tricks pointed out that you can let your users edit the CSS in real-time. Because the <style> element is set to display: none by the user agent, we need to set it to block for this code to work.

Try editing the CSS below:

Live CSS editing

Browser Support

Browser support for contenteditable is surprisingly good:

Browser Support for contenteditable
Browser Version
Chrome 4.0+
Safari 3.1+
Mobile Safari 5.0+
Firefox 3.5+
Opera 9.0+
Opera Mini/Mobile N/A
Internet Explorer 5.5+
Android 3.0+

We have to give credit where it’s due and point out that Internet Explorer has supported this attribute since IE5.5. In fact, a very early iteration of contenteditable was designed and implemented by Microsoft in July 2000.

For a more in-depth compatibility table, visit When Can I Use….

Storing the Changes

For this section, I went straight to Doctor Remy for help, as he is much more knowledgeable than me when it comes to storing your data everything.

Depending on the complexity of your editable block, your code could be listening for the enter key (keyCode 13) to save the changes, and the escape key (keyCode 27) to undo the changes.

When the user hits enter (assuming it’s a single line of editable content), it would grab the innerHTML of the editable field and send an Ajax post to your server with the change.

A simple example of this can be seen on JS Bin: contenteditable saving to Ajax

Conclusion

We’ve repeated the phrase “paving the cowpaths” all over this site, and I’m mentioning it again with the introduction of the contenteditable attribute. The spec finally makes official something that’s been implemented by browser makers for years.

Although this is one of the lesser-known new attributes, I bet you’ll find yourself using it more often than you would think.

Imagine being able to simply click a block of content and start making changes instantly: making quick corrections to an article in-place, allowing users to edit their comments, or even building spreadsheets within company applications that aren’t hooked up to any sort of back-end user interface.

If you can think of other uses for this attribute, then head on down to the comments section and tell us where else you think this could be implemented.

38 Responses on the article “The contenteditable attribute”

Vidal Quevedo says

Wow, I just had an “aha!!!” moment with this article: editing css directly on the browser?? My mind just exploded!

Thanks for sharing, Jack!

Jack Sleight says

Does the spec cover how input to contenteditable elements should be handled? In my experience these are the biggest stumbling blocks when trying to use contenteditable, and certainly something that needs standardizing. For example something as simple as what happens when a user hits return, new paragraph or line break? There are inconsistencies here.

Also, are there any efforts to standrdize and improve document.execCommand(), or replace it with something better?

simurai says

Live editing of the element is really cool.

You can also make any element editable with the CSS property user-modify. It’s pretty handy while prototyping.

Alejandro Moreno says

I don’t know what’s the problem with this site’s markup, but the page is not scrollable with arrow keys, pgUp nor pgDn in Firefox 10.0 Beta on Windows. Trying to scroll up takes me right to the top, and scrolling down takes me right to the bottom, which makes reading very uncomfortable.

Now I’ll try to keep reading, and remember that I can’t use the keyboard on this site.

Alejandro Moreno says

Keyboard-grouchiness aside, this post reminds me of a portable one-page wiki that consisted of a single HTML file. The file included styles and javascript to support wiki text, or Markdown, and the user would simply have to save the HTML file to disk to preserve changes.

The idea was kind of cute at the time.

Chad Ostrowski says

Mercury Editor is an open-source WYSIWYG editor that primarily uses contenteditable. It’s still pretty young, but I’m excited for its future.

I’ve already used contenteditable in a project to allow users to edit small bits of text. You can make one project-wide jQuery method that binds to any elements with contenteditable attributes, and just listen for keyup and if it matches 13 (I think that’s return?), send blur the element and send the new value to the server. I also set a data-original attribute on these elements with the original value of the element, so I don’t have to send unnecessary updates to the server.

Dave says

Here is a fun example with the contenteditable attribute.

Just paste this data-url to your browser and then edit the title or the style of the whole page

data:text/html,<title contenteditable>Hello World</title> <style contenteditable>head, title, style {display: block;}</style>

Another thing is that you can create a notepad with just one short url:data:text/html,<html contenteditable></html>

Pretty cool I think.

Albert says

I’ve tested it on Internet Explorer 6 & 7 and it doesn’t work.

Are you sure the compatibility table is right? :-)

Anyway, nice article!

Szigyártó Mihály says

If you use this attribute in tables, you should pay attention to browser flavors, like there:

* IE doesn’t support contenteditable in tables
* Chrome and Firefox puts some extra characters after editing (i can’t remember which is which, but extra characters can be spaces and br tag)

Jack Sleight says

@zcorpan Thanks!

Richard Clark says

@Alejandro, You’re right, I’ve just tried this on FF10 on Mac and get the same issue with up & down keys but not pgUp & pgDown. However, it seems to be restricted to this one article for me. Are you having issues with other pages on the site?

bigbossSNK says

Firefox is buggy with contenteditable.

If there’s a contenteditable element in the page, you can select but you can’t copy content on non-contenteditable elements.

Mixing contenteditable with -moz-user-modify:read-only doesn’t work, whereas it works for Webkit.

ArtFaks says

Thanks, very good article on this new html5 property!

This property was still already present and use in the Apple Mail for these stationery!

;-)

neb says

Have the elements ‘input’ and ‘textarea’ this attribute = true? Or is the editing of input/textarea using some other mechanisms?

Christian Sciberras says

Some people are really clueless it seems… As the article mentioned, contenteditable has been there are least 12 years ago, where’s the novelty in that? Editing CSS directly in the browser? No duh…what do you think Firebug / Dev Tools do?

Craig Barnes says

You are using the cite element to attribute a blockquote to Remy Sharp.

Oops. Did you actually pass medical school or are you just one of those phony, discount Plastic Surgeons?

Craig Barnes says

@Jack Osborne, @Richard Clark

Haha, just trolling you. How’d I do?

thinsoldier says

@dave: even shorter

data:text/html,<body contenteditable>

swati choudhary says

grt info…

Can u pls explain how to save the editable text using html5??

ArtFaks says

Cookies or php script for this !

swati choudhary says

That means, its a backend work only???

ArtFaks says

Yes, sorry i think !

swati choudhary says

Ok
Thanks a lot for this info

Vikram Goel says

I have tried contenteditable=”true” it was working fine. But when i added draggable=”true”, both functionality(draggable and contenteditable) stopped working.

Any idea why ?

html5gamedevelops says

I like it pretty much but how about sending that edited info into the database?

Programaths says

Hi,

I tried copy pasting a table, it worked !
One step further, I edited a document in LibreOffice and copy pasted…It worked !

I know this is dirty but I am going to use this to let user edit fragment in the way they are used to !!!
(they feel more in ease to copy/paste from word than using an inline editor !)

@html5gamedevelops
To send content to database, you may do it through REST.
JQuery (.post) can assist you in doing so.

Alternatively, you could copy the HTML content of your “contenteditable” into a hidden textarea through JavaScript.
When the user would submit the form (yes, should be part of a form), then the textarea would be posted.

KR,
Programaths

upender says

and how to store it
i have done with all query to store and retrieve it but when i refresh the page it coming to default

I want to edit the content and save it and show the resultant content even i refresh the page

please help me ……..

thanks

Pradeep Chowdary says

Really nice stuff..Saved my entire day work :)

Joe says

upender you are going to use a cookie for what you want to do and that could make things COMPLICATED, but if you must here is a good link to get you started: http://davidwalsh.name/php-cookies

brothercake says

contenteditable regions should also have tabindex=”0″ to make them keyboard accessible.

Mufaddal Shabbir says

I just got a requirement, when someone type in element, element increases width according to text, for this requirement its perfect match. Also its easy to use.

webguy says

There is a lot of confusion about this attribute, in-fact this attribute is very old, its part of the HTML 4 specification for more than a decade, its accessible also in the JavaScript API (possibly since even 1.2) since 2000 or even earlier, which is when I first used it, so its possibly pre 2000. What has changed is that it was only possible to use it on certain elements, the original being the iframe, then later support was added for other markup elements, but from what I can tell HTML5 adds the ability to use this attribute on many more elements than before so its more prominent.

Arun says

It is still not working in IE 11. There is no problem with “contenteditable” attribute, that works fine on elements, but it seems it does not recognize “data URL”.

Any suggestions please.

Join the discussion.

Some HTML is ok

You can use these tags:
<a href="" title="">
<abbr title="">
<b>
<blockquote cite="">
<cite>
<del datetime="">
<em>
<i>
<q cite="">
<strong>

You can also use <code>, and remember to use &lt; and &gt; for brackets.