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 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".
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.
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:
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….
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
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.
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?
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.
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.
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.
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)
@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?
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?
I have tried contenteditable=”true” it was working fine. But when i added draggable=”true”, both functionality(draggable and contenteditable) stopped working.
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.
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
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.
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.
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”.
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
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.
Sorry, I forgot to escape the non-breaking space above:
Further testing after my comment above, a final IS recognised correctly.
That is really not that helpful, unless one wants to always replace a final space with an ,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.
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!
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!
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?
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.
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.
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 withcontenteditable
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 adata-original
attribute on these elements with the original value of the element, so I don’t have to send unnecessary updates to the server.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.
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!
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, see http://dvcs.w3.org/hg/editing/raw-file/tip/editing.html
@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?
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.
Thanks, very good article on this new html5 property!
This property was still already present and use in the Apple Mail for these stationery!
;-)
Have the elements ‘input’ and ‘textarea’ this attribute = true? Or is the editing of input/textarea using some other mechanisms?
Try the http://aloha-editor.org/ ce. at it best!
Greez Jens
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?
You are using the
cite
element to attribute ablockquote
to Remy Sharp.Oops. Did you actually pass medical school or are you just one of those phony, discount Plastic Surgeons?
@Craig Barnes: a discount plastic surgeons.
@Craig Barnes – The spec isn’t gospel and we disagree. See Oli’s article on blockquote, q & cite.
@Jack Osborne, @Richard Clark
Haha, just trolling you. How’d I do?
@dave: even shorter
data:text/html,<body contenteditable>
grt info…
Can u pls explain how to save the editable text using html5??
Cookies or php script for this !
That means, its a backend work only???
Yes, sorry i think !
Ok
Thanks a lot for this info
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 ?
see this post to parse text from content editable div
http://stackoverflow.com/questions/12821102/how-to-parse-editable-divs-text-with-browser-compatibility
I like it pretty much but how about sending that edited info into the database?
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
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
Really nice stuff..Saved my entire day work :)
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
contenteditable regions should also have tabindex=”0″ to make them keyboard accessible.
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.
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.
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.
This is nice:
data:text/html,Hello World head,title{display: block;}
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
A simple example of this can be seen on JS Bin: contenteditable saving to Ajax
— Remy Sharp
Link doesn’t work
fixed now, thanks for pointing out.
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.
Sorry, I forgot to escape the non-breaking space above:
Further testing after my comment above, a final IS recognised correctly.
That is really not that helpful, unless one wants to always replace a final space with an ,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.
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!
Join the discussion.