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 . 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.

45 Responses on the article “The contenteditable attribute”

  • 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.

  • 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!

  • @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?

  • Jens says:

    Try the http://aloha-editor.org/ ce. at it best!

    Greez Jens

  • 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?

  • Jack Osborne says:

    @Craig Barnes: a discount plastic surgeons.

  • @Craig Barnes – The spec isn’t gospel and we disagree. See Oli’s article on blockquote, q & cite.

  • 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 ?

  • 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.

  • Kevin Cassidy says:

    This is nice:

    data:text/html,Hello World head,title{display: block;}

  • Howard Cary Morris says:

    Some browsers work funny, seeing 2 strange results:
    1) When I Print Preview – not showing changes I made properly
    — Safari
    2) Copy paste seems to copy font settings as well overriding CSS
    — Safari
    — Opera
    — Chrome

  • Lonesta Jack says:

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

    Link doesn’t work

  • Patanjali says:

    Note that IE11 (and possibly earlier versions) doesn’t show a final space.

    Specifically, the last space is shown outside the containing element, which may give an editor the sense that it isn’t there, as it will not take on the background-color of the containing element.

    The giveaway is that pressing the End key will put the cursor after the space, outside the element, but clearly ‘invisible’ if the element isn’t the focus.

    Unless there is a way to give a background colour to the text itself, as opposed to its containing element, contenteditable is likely to be a frustrating exercise for those using IE11.

  • Patanjali says:

    Sorry, I forgot to escape the non-breaking space above:

    Further testing after my comment above, a final &nbsp; IS recognised correctly.

    That is really not that helpful, unless one wants to always replace a final space with an &nbsp;,whether entered while editing or retrieved, then restore it as a normal space when saving.

    May be worth it though, if it allows in-place editing, which will obviously require a lot of javascript usage to properly implement anyway.

  • Tim H says:

    I’ve been unsuccessful trying to use this with Salesforce. That is, with APEX (ex: apex.inputField). I am unable to save the data the user inputted. Any ideas or help is appreciated!

  • Leave a Reply to swati choudhary

    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.