World Simplest HTML5 WYSIWYG Inline Editor

I am pretty new to web/JavaScript development, and often quickly reach for Google in order to find out how to do things.

Recently I needed to add the ability to do some pretty basic in-page editing of content. I didn’t want to use iFrame’s, i didn’t want a hugely featured editor, literally some pretty basic tools to be able to edit content, bold, italic, h1, h2 and so on.

After a fair bit of Googling, it seemed that there wasn’t a hope! all the plug in’s i found just seems unnecessarily complicated so, in a fit of self-importance, i decided i could do it myself. i’d end up with the editor i wanted, and code that i fully understood. Granted, it wasn’t likely to be an easy job, but hey, why would i code anything if there was an easier option?

To my surprise, as it turns out, it’s so simple, it’s almost a joke! all the tools are already available, all you need to do it tie them together with some really simple JavaScript, and it works!

There are two things you need, the first is

contenteditable

contenteditable tells the browser that this item (a div for example) can be edited inline. You can do all the normal text editing here with ctrl-b for bold, ctrl-i for italics etc, but it’s fairly limited.

The second thing you need is a special function called

execCommand

execCommand actually allows us to do some fairly complex stuff with the contents of the contenteditable area, and all in a really compliant way!

If you want to read what it can do in detail, check out The Mozilla Docs

Essentially, execCommand takes three parameters:

Command Name – the name of a command
ShowDefaultUI – not implemented, and best set to false
ValueArgument – optional for some commands so for example, using the command ‘bold’ will make the currently selected text turn bold with a <b> tag!

ValueArgument can be set to null in all but one case. When you want to set a tag for a line of text (h1, h2 for example) you need to use the formatBlock  command, and put the tag you want in the ValueArgument (without angle-braces).

Now this is simple enough, but to make life even easier, a single click handler and a data-attribute on each link allow us to have one very simple function to handle everything.

The demo uses bootstrap and jQuery, but only to make the code a little more brief, and could all easily be done in plain old JavaScript.

Check out this Pen!

EDIT: CompuSam suggested using

href='javascript:void(0)'

instead of

href'#'

to stop and unwanted page movements etc....

  • http://www.barneyparker.com Barney Parker

    Any mistakes or errors, please let me know!

    And if you have any comments on how I’ve done things, i’ll be happy to update the article!

    • http://Website Wrought_steel

      Hate to point out the typo in the headline but… WYSIWYG rather than WYSISYG

      • http://www.barneyparker.com Barney Parker

        Ten points to you Wrought_Steel! This article has been view, pinged, tweeted and a whole host of other things, and you;r the first to notice!!!! I can’t believe i made such a stupid error!!! Thanks for pointing it out, i’ve updated it now!

  • http://Website Andres Sainz

    Great work!

    I’ll be implementing this, since most of the times i need only this basic edition, but i end up using a big library.

    • http://www.barneyparker.com Barney Parker

      Thanks, I hope it works well for you! Let me know!

  • Pingback: The World’s Simplest HTML5 WYSISYG Inline Editor | Wireframenews

  • http://www.bacondrivencoding.com/ Sean McMillan

    A couple of years ago, when I looked into contenteditable, there were _huge_ pitfalls cross-browser. Is it better now?

    • http://www.barneyparker.com Barney Parker

      Well I’ve tried it on the major browsers and it’s looking pretty good. From what I can tell it’s been added to pretty much all of them now, although if anyone find different, i’d be interested to know…

      • http://Website Nathaniel Price

        My experience has been that simple stuff like what is presented in this blog entry has decent support, but there are still plenty of cross-browser compatibility issues. For instance, many of the built-in commands generate different markup in each browser, which can make things difficult if you’re trying to normalize that markup.

        There are also generally many other subtle differences in behavior between the various contentEditable implementations, since it has historically not been well standardized, and even the HTML5 spec seems incomplete and leaves a lot of wiggle room for browsers to do things differently from each other. http://www.w3.org/TR/2008/WD-html5-20080610/editing.html

    • http://jasoncrawford.org/ Jason Crawford

      MDN says “fully compatible with current browsers”: https://developer.mozilla.org/en-US/docs/Web/HTML/Content_Editable

      caniuse.com says it’s compatible with the current version of everything except Opera Mini: http://caniuse.com/contenteditable

      So yeah, looks pretty good.

      • http://www.barneyparker.com Barney Parker

        Thanks Jason, yes it looks like it’s “mostly” compatible with current browsers, although there does seem to be some quirkyness to it. Hopefully with a little more testing i can iron some of the oddities out, and get it really solid! For 14 lines of JS, it’s certainly not bad right now!

  • http://Website Benjamin Milde

    If you choose sub/superscript you can’t change it back to normal, without going backwards and undo a lot of other stuff. But everything else is executed quite well. Nice job.

    • http://www.barneyparker.com Barney Parker

      Well spotted Benjamin, I’ll take a look and see if i can fix that!

      • http://Website Spencer

        TL;DR:
        sub { vertical-align: sub; }
        sup { vertical-align: super; }

        Funny enough, I was recently implementing my own editor and came across this exact issue. I had assumed the problem was caused by the browser’s compatibility with `execCommand`. Turned out that the problem has to do with how Bootstrap (more precisely how Normalize) styles the subscript and superscript tags. I filed an [issue](http://github.com/twbs/bootstrap/issues/8998?source=cc) with Bootstrap’s repository, but ultimately the change would need to occur in Normalize.

        • http://www.barneyparker.com Barney Parker

          AAaaaaahhhh!!! that explains a lot!

  • Pingback: The World’s Simplest HTML5 WYSISYG Inline Editor » KnowYourUser

  • http://www.williams-forrest.com ljc

    One question: Is this IE8 compatible? LOL

    • http://www.barneyparker.com Barney Parker

      That’s a really good question! I only have IE10 right now, so if anyone had IE8 installed, i’d love to know myself!

      If i find out, i’ll reply ASAP!

      • http://Website Dane Weber

        It all works great in IE8 now!

        • http://www.barneyparker.com Barney Parker

          Thanks! :)

      • http://Website Alexander Vakhlov

        I’ve tested demo using IE8 – it works fine! -)

        • http://www.barneyparker.com Barney Parker

          Thanks for testing!

      • http://dfinfotech.com David Furman

        With IE 10 you can check all previous versions back to IE 7 using the F12 Developer Tools. There is an option at the top of developer tools to set the browser mode to previous versions of IE.

        • http://www.barneyparker.com Barney Parker

          Wow, I never knew that!!!

          OK, when i get a little time later today i will check that out and see how far back we can make this work!

        • http://Website Anthony Garritano

          A note on this -You have to be careful with those developer tools. My understanding is that it _emulates_ older versions of IE; meaning it doesn’t render things the way the actual version will. I’ve heard of new bugs being introduced and the bugs present in older versions not being in the dev tools version. Really confusing and unreliable.

          I currently use BrowserStack.com. The faster your internet connection the better it the service is.

          • http://www.barneyparker.com Barney Parker

            I’ve not used BrowserStack, but i’ve heard good things about it, i’ll give it a try!

          • http://Website O’Ryan

            BrowserStack also has a bunch of weird quirks. I’ve run across strange bugs in older versions of IE that only existed in browserStack’s implementations of those browsers. I could never repro them in the local versions of the same browsers. And there were some bugs that didn’t happen in BS… Too many times have I spent many hours banging my head against a problem only to find out it was a BS isolated issue.

            I have a few VMs dedicated to Cross Browser testing now. I don’t much trust BrowserStack. Unfortunate, because it was quite handy.

      • http://www.dopefly.com/ Nathan Strutz

        Yeah IE8 seems to work. I don’t know about submitting a form with it, I assume that’s gotta be done with javascript – a little jQuery will do you just fine. The only thing that didn’t work in my IE8 with your demo is the Font Awesome icons you put on the buttons – for some reason I can never get them to render in IE8.

        • http://www.barneyparker.com Barney Parker

          Yeah, I am pretty new to web development, so I’m not 100% sure why the font-awesome icons are being so troublesome.
          I’ll definately be trying to fix that with a follow-up article, there’s a lot to add now!

    • http://Website Daniel

      I recall using this in IE6 years ago (with the usual gotchas you may expect).

      • http://www.barneyparker.com Barney Parker

        Wow, so it was supported at least partially that far back? That’s pretty impressive!

  • Pingback: The World’s Simplest HTML5 WYSISYG Inline Editor | David Tufts

  • http://michaellwest.blogspot.com Michael West

    The bold, h1, h2 seem to have problems in IE 10.

    • http://www.barneyparker.com Barney Parker

      Interestingly I see the bold working fine in IE10, but h1 and h2 don’t seem to…. I thought i’d checked that!!!

      OK, give me a little time and i’ll see if i can fix that!

    • http://www.barneyparker.com Barney Parker

      OK, so i’ve fixed it in the demo code!

      It seems that IE wants you to add the angle brackets in the third parameter. I’ve not tested in all browsers, but it looks like chrome at least doesn’t mind them being there…

      The code has changed from
      document.execCommand('formatBlock', false, $(this).data('role'));

      to

      document.execCommand('formatBlock', false, '< ' + $(this).data('role') + '>');

      if there’s no further problems i’ll update the code in the post….

  • http://Website Dane Weber

    It mostly works in IE8 (v. 8.0.7600.16385). H1, H2, and P are not working, but it looks like that might be overlap with broader IE issues (since Michael West says that IE10 has issues).

    • http://www.barneyparker.com Barney Parker

      yeah, IE, the usual suspect…. I’m not sure of the best way to handle it, maybe gracefully degrade (or progressively enhance!) depending on what can be supported….

  • http://Website Noel

    Works in IE8 – nice job. I would definitely use it if there was a way to see the HTML that is written. Like a view HTML source button

    • http://www.barneyparker.com Barney Parker

      I agree, I’d like to do a follow-up with something like this in it, not 100% sure how, but it’s can’t be hard (ever the optimist!)

      • http://crocodillon.com/ CrocoDillon

        `$(‘#editor’).html()` (or without jQuery, `document.getElementById(‘editor’).innerHTML`), just need to format it nicely, which is the real pain I guess :P

  • Pingback: The World’s Simplest HTML5 WYSISYG Inline Editor | RizveJoarder WP Freelancer

  • http://dropforge.org/packages/xandarella Stephen Bounds

    Hi Barney,

    Your experience backs up mine, that the “contenteditable” approach is quite viable now for simple WYSIWYG tasks.

    I built a slightly more complex approach for myself that allows custom buttons for non-built in commands to support things like pop-up prompts for links and images, and dropping back to pure HTML editing. But it’s essentially the same technology.

    My source code is here if you’re curious:
    http://dropforge.org/demo/xandarella/scripts/jquery.rte.js

  • Pingback: Agency Geek » What could possibly go wrong? » World Simplest HTML5 WYSISYG Inline Editor

  • http://stardotbmp.com Jonathon

    Perhaps a webkit/apple thing, but if you set text to H1 and then Numbered Bullet, the number is off the left of the textarea.

    Chrome 29b OSX10.8.4

    • http://www.barneyparker.com Barney Parker

      There does appear to be some variance in the way different browsers generate the markup to format the text. I must admit I’ve not tested it aggressively, but it’s interesting to see that the built in functionality doesn’t always seem to be as accurate as it might be.

      I’ll take a look at the execCommand specs and see if I can work out some way to fix that one….

  • http://Website madhu

    This might be a stretch, but is it possible to have a way to add links. Select a piece of text, click a button to add some links.

    • http://www.barneyparker.com Barney Parker

      Definitely! there’s a command to add links, and a few other things such as images etc. I didn’t implement them as I was going for the most minimal code i could. There’s been a lot of interest though, so in a follow-up article I will go a bit more fully featured!

  • http://artlung.com/ Joe Crawford

    Cool stuff. See http://caniuse.com/#search=contenteditable for a bit of the supposed compatibility. It also includes links to more about contentEditable.

    • http://www.barneyparker.com Barney Parker

      @Joe Crawford Thanks for the link, i think i’ll move that up in to the main post, that’s a pretty useful bit of info to have!

  • http://Website Eric S

    Judging by our user agent logs and contenteditable support listed at caniuse.com, the Android 2.3 browser is going to be our largest speed bump to implementing this as far as just plain support existing (not that I expect things to go perfectly smooth, I’m sure there will be cross browser issues).

    Thank you.

    • http://www.barneyparker.com Barney Parker

      Yeah, the older Android browsers seem to be really hit and miss, I’m not sure there’s a huge amount that can be done, except perhaps graceful degradation to remove the offending buttons that cause issues….
      worth some further investigation though!

  • http://itsricky.com itsricky

    This is PERFECT! I’ve been looking for something like this approach for ages, and like you mate found a whole lot of bloated plugins with 1001 features each.

    I wanted something simple like Basecamp’s editor – super simple.

    I found an article on Stack Overflow for that, and realised you needed JS Ninja skills to implement – so this simpler more lightweight solution is great!

    Thanks for sharing :)

    • http://www.barneyparker.com Barney Parker

      @itsricky – No problem, glad it’s of use! I was in exactly the same position and this just seems so simple it’s hard to believe!

  • http://Website MKJ

    Works pretty good in IE8. Thank you for sharing!

  • http://Website b_b

    I just tested it at work on a good, old IE 7. The buttons at the top show up as grey rectangles only, with text on it if there’s any (i.e. “Bold”) — the images are missing. But apart from that it seems to work well. Didn’t expect that ;-)

    • http://www.barneyparker.com Barney Parker

      Wow, i didn’t expect that either!!!

      I guess the icon may be an issue as they are using the font-awesome set. all the images are in the unicode user area, so i’m not sure if IE7 supports either web fonts or unicode characters!

      I’ll see if there is some way to do a fall-back to something more basic….

  • http://info.org.il Hanan Cohen

    I miss an LTR-RTL paragraph direction button. Not all the world writes from left to right.

    • http://www.barneyparker.com Barney Parker

      Very good point! The text reading direction is not something that i have set, do you know if this is something a browser would do by default if your regional settings include this? I feel some testing coming on!!!

  • Pingback: World Simplest HTML5 WYSISYG Inline Editor | ve...

  • http://jeroenransijn.nl Jeroen

    Very bare-bones and awesome! Two things pop up though, first, if I recall correctly execCommand is a page wide event, so how does this work with more instances? Is it possible to get the state of a selection reflected in the toolbar — if I select a header I expect to see the header button toggled in the toolbar. ~ Jeroen

    • http://www.barneyparker.com Barney Parker

      OK, so that’s a really good pair of questions!

      • As far as i know execCommand works on the current selection only. As such it shouldn;t be a problem having multiple contenteditable areas on a page since you can’t select multiple areas…
      • I don’t believe there is any way to find the current state of the text. I guess it would be possible to scan the text back from the current location on a click event and see if you can determine it that way, but i’m not sure how easy that might be since different browsers alter the markup in different ways…..

      Any suggestions would be welcome though and i’ll see what i can do!

  • http://Website Tanny O’Haley

    I’ve had several problems with Chrome. One was that I was getting a javascript error when turning off insertUnorderedList and insertOrderedList. My solution was to check if that was the command and use the queryCommandState function to see if they were already set and change the command to ‘outdent’.

    var command = $(this).data(‘role’);
    switch(command) {
    case ‘h1′:
    case ‘h2′:
    case ‘p’:
    document.execCommand(‘formatBlock’, false, command);
    break;
    case ‘insertUnorderedList’:
    case ‘insertOrderedList’:
    if(document.queryCommandState(command)) {
    command = ‘outdent’;
    }
    // no break lets it flow to default.
    default:
    document.execCommand(command), false, null);
    break;
    }

    I didn’t test it in IE, but it worked in Safari, Firefox, and Chrome. There are other browser differences with each implementation of the rich text editor. Good luck and nice code. :-)

    • http://www.barneyparker.com Barney Parker

      Thanks Tanny, really appreciated!

      I like the code you added, and it’s uncovered a few additional things i didn’t know!

      I have quite a few adjustments to make from all the comments, so i feel another post coming on to update things!

  • http://Website Alex_PK

    I implemented a contenteditable editor in the last couplo of years for a self-made CMS.

    I had a lot of problems using ‘a’ for the formatting buttons, especially when you use selected regions, as the region gets unselected just before the action gets called.

    • http://www.barneyparker.com Barney Parker

      Interesting, I’ve not come across this, but I will also admit I’ve not tested it to death so i may have just not spotted it yet….

  • http://markdown-here.com adam-p

    `contentEditable` (and `designMode`: https://developer.mozilla.org/en-US/docs/Rich-Text_Editing_in_Mozilla) is used by mode webmail clients (and Thunderbird) to provide rich editing. I created a browser extension called Markdown Here (http://markdown-here.com) that allows you to write email in Markdown and then render to HTML — in a `contentEditable` field. So, happily, it works in the example you gave.

    (…With some caveats. I haven’t tested everything, but I can see that there are some styling conflicts with the Bootstrap defaults — such as for code blocks. Anyway, still cool.)

    • http://www.barneyparker.com Barney Parker

      That’s really cool! I like the idea of just using simplistic markup (or markdown) to render in to full HTML!

  • http://Website Dave Houlbrooke

    Tiny quick fix:

    On iOS, the page submits after tapping the toolbar buttons, so either the default behaviour needs to be cancelled, or switch to instead of empty ‘a’ tags.

    The downside to this super-stripped-back WYSIWYG is security, unfortunately. If someone pastes a malicious script in here it’ll execute and have access to the entire frame, which is why most text editors isolate the contenteditable area in an iframe. (Also handy for isolating CSS styles.) After you use an iframe though, you get various compatibility problems with different browsers though. This is the main difficulty in building a really solid WYSIWYG editor.

    • http://www.barneyparker.com Barney Parker

      You’re right, they could certainly paste malicious code, but to my mind, it would be limited to the client as long as you clean the data before using it on the server side?

      Anyone have any examples? I’d be really interested to see it since it would certainly begin to explain why i haven’t really seen this documented elsewhere…

    • https://twitter.com/reinmarpl Piotrek Reinmar Koszuliński

      @Dave: I haven’t heard about browsers preserving scripts (neither nor on* attributes) in clipboard. Editors use iframes for other reasons – http://stackoverflow.com/questions/11202534/html-wysiwyg-edtor-why-is-the-editable-content-moved-in-an-iframe

  • Pingback: The World’s Simplest HTML5 WYSISYG Inline Editor | Affordable Website Design - Wordpress Website Development

  • http://Website J

    iOS 6 has a bug when contentedotable is on: clicking in the text and then a textarea (within the same div) will cause a crash. I’ve reported that, as have others, and hopefully Apple is fixing it.

    • http://www.barneyparker.com Barney Parker

      That’s good to know; I don’t have an iPhone or iPad, so haven’t had the chance to test myself (although a couple of friends tell me it’s OK on their devices)

    • http://Website Tanny O’Haley

      That’s interesting because it works in IOS 5.

  • http://eduardmoldovan.com Eduárd

    Hey Barney,

    This is great. Perfect! I was planning to do this in a while, but I just played around with it.
    One question: you style the markup in the “default” way. Have you considered using document.execCommand(“styleWithCSS”, null, true); for making the browser style stuff with CSS?

    Also, CKEDITOR has something similar, but with way more JS. i used that in a project of mine (actually I write my posts in that – it is part of my blog engine).

    But again, great stuff!

    • http://www.barneyparker.com Barney Parker

      I have to admit, I’ve not checked out the “styleWithCSS” command, but in principal it looks like it could be pretty useful. As i mentioned in the article, the way different browsers actually embed markup can vary quite a bit.
      I guess potentially the styleWithCSS command might give us the opportunity to fix our CSS the way we want it.
      The bonus would be that it would be far easier to work out what our current style is with window.getSelection().anchorNode.parentNode;
      Definitely something I need to think about!

  • http://andrewensley.com/ Andrew Ensley

    Thank you for sharing. This looks like exactly the kind of solution I’ve been looking for!

    One question: Are there any security concerns with this method of input? What I mean is, is it possible to paste some HTML into the “editor” that might have some nasty XSS code in it?

    • http://www.barneyparker.com Barney Parker

      I’m not sure why it works, but it seems if you type or paste in and tags, they’re treated as plain text.
      To be fair though, I’ve not tried reloading with edited text (i.e. store the text in a db and then retrieve it for a new page load)
      in this case i guess it’s down to the dev to make sure they handle it properly….

    • https://twitter.com/reinmarpl Piotrek Reinmar Koszuliński

      AFAIK browsers do not keep scripts (script tags and on* attributes) in the clipboard, so pasting should be safe. However, when you load data with malicious code from your DB, that code will be executed, so you need to clean it.

  • http://sallar.me Sallar

    The biggest problem I have with contenteditable=true is formatting. Like when you paste a text and it has it’s old formatting/fonts/etc. I tried to remove the formatting when pasted automatically, but it wasn’t ideal. I tried to catch the meta+v and create an empty hidden textarea on the fly so the pasted text would go in that instead of the contenteditable=true div, and then move the textarea’s content to the div’s caret positon! but it was not nice and didn’t work that good.
    Any suggestions? Thanks.

    • http://www.barneyparker.com Barney Parker

      Hmmmm, that’s a good question. You’re right, it’s certainly not ideal to paste formatted text in to the field, and it seems you can copy and paste web code in too and see it fully marked up.
      I guess ideally we need some way to capture the pasted content, cleanse it of any tags etc, and then allow it to paste in, but i’m not sure of a simple way to do it.

      Any ideas anyone?

      • http://Website Tanny O’Haley

        I know it’s old, but Cameron Adams created a simple editor way back in 2005 and hasn’t updated it since 2008. One of the features is that it would clean and normalize the HTML. It would even automatically cleanup awful HTML pasted from Microsoft Word. Sad he hasn’t updated the code, but it is there for people to use.

        http://www.themaninblue.com/writing/perspective/2008/03/02/

        • http://www.barneyparker.com Barney Parker

          Now that’s pretty cool! To be honest, if anyone was considering extending the code in this article, your link to Cameron Adams’ clean-up code is definitely worth the read!

        • http://sallar.me Sallar

          Thanks! I’ll definately look this up.

    • http://www.ignition72.com Joe

      I fought with pasted content for our implementation, and finally settled on grabbing the entire container and sending it via an onpaste ajax call to the server, post-processed it with PHP and REGEX, returned a nice clean chunk of code.

      The bold issue some commenters brought up in IE may be because IE uses strong tags instead of bolds.

      Makes for real hell in making a cross-platform cross-browser editor!

      • http://www.barneyparker.com Barney Parker

        you’re so right, in fact it’s almost an unusable solution!

        As it happens, many companies require the use of a specific browser, and in this case it can be a real life saver, since you can be sure the code will be workable no matter who edits. in every day situations though, i’d definitely recommend something more complete!

  • http://www.kkatusic.com kkatusic

    Very nice and simple editor, maybe I will implement it in one of my drupal website.
    Can I add some features to it, like button for link, etc?

    • http://www.barneyparker.com Barney Parker

      You sure can! If you take a look at the MDN link in the post, there is a createLink command. It basically adds an anchor and an href using your current selection as the link text. I wanted to include it, but the extra code to get some user input bulked the code a little, and i was going for a minimalist thing!
      I’m doing an update post in the near future, and that’s one thing i definitely want to add!

  • https://twitter.com/reinmarpl Piotrek Reinmar Koszuliński

    Disclaimer: I’m a CKEditor core dev; CKEditor uses contenteditable :)

    I have to admit – I have a lot of fun following “contenteditable” keyword on Twitter :). Dozens of devs discover the contenteditable every day (and I believe that most of them thinks that “WYSIWYG has been finally solved”) but just few realizes how bad it is. Don’t get me wrong – I’d react exactly the same way if I wasn’t warned by one of the few people who spent years working on WYSIWYG editor.

    Have you ever thought why CKEditor’s main JS file weights 300KB (minified, not gzipped – 98KB after gzipping) in case of a **basic package** (basic package has theoretically even less features than your editor)? Just mention that we write code that minifies well and we avoid adding not really necessary features.

    The reasons are simple (at least for me, after 1.5 year of struggling with contenteditable :D).

    Contenteditable’s implementations (and related like selection, focus, etc.) are buggy and limited. And if you want to imagine this situation, then think of the web 10 years ago. And I don’t mean only IE – recently my “favorite” engine is Blink (Chrome, Chromium), because it’s being actively mantained, so from time to time there are new surprising “features” like http://dev.ckeditor.com/ticket/9998 (https://code.google.com/p/chromium/issues/detail?id=226941).

    Contenteditable is very limited and inextensible – whatever you’re trying to add or change that exceedes its capabilities, you’re doomed. For example – more robust styling system (because you don’t like that browsers use <font> tags or you want to apply span with class); enter/delete key (have you tried to play more with enter & delete keys in native contenteditables?); pasting (cleaning that crap); undo (browsers do not record everything and sometimes you want to not record some changes), etc, etc… There’s really a lot here – I don’t find any of the implementations’ parts acceptable. Of course – if someone needs a limited number of features, then he needs less patching, but even the basic editor means a lot of work. For example – the standard CKEditor’s build which is a typical for a content like a blog post has 440KB (main JS file, minified, not gzipped), so not a big difference comparing to the very limited basic build.

    Every single feature which is related to selection, DOM operations, contenteditable and HTML processing is complicated. It’s hard to give an example, because a lot of core code is reused in many places, but e.g. I estimate data processing and filtering (including capturing pasted content) for 4k LOC (+2.5k comments). The range, selection, DOM operations and DOM processing code which is reused by nearly every feature in editor (like enter, styling, lists) is 7k LOC (+4k comments). And then you have UI, bootstrap code, plugins, and translations APIs and many more… BTW. jQuery 1.10 has 8k LOC.

    The conclusion is – don’t try to build your own editor unless you really know what you do and you have a lot of time.

    • https://twitter.com/reinmarpl Piotrek Reinmar Koszuliński

      Sorry for formatting… This WP is configured to strip it at all (tried both – HTML and text).

    • http://www.barneyparker.com Barney Parker

      I absolutely cannot disagree with you with regards to the feature set and reliability aspects of my little WYSIWYG editor and that of CKEditor.

      What i will say however is that i just don;t need the vast majority of the functionality that i saw in every “off the shelf” editor i found!

      Look at it this way. MS Word has thousands of really amazing features. Love it or hate it, MS word can do just about everything a Word Processor could ever need to do.

      How many functions does the average user use? Around 10-20….

      In all honesty, this code is no where near as complete as CKEditor, but i neither wanted it to be, nor needed it to be!

      And I completely disagree with your conclusion. I don;t come from a web dev background, I come from IT Infrastructure, embedded systems, satellite communications. I grew up in a world where 8 bits was great, 1MB was a huge amount of memory and 56K internet was fast. In all my years, one thing i have learnt is that if we all just accept that what we have now is either the best it can be, or the only way it can be, we miss out on a huge number of opportunities to make things better. It’s amazing what’s already been invented. Everything in the web world has been around for decades, but like every generation, we all think it’s new and we invented it.

      We didn’t. Learn your history, and learn that new ideas are rare, but definitely worth listening to….

      • https://twitter.com/reinmarpl Piotrek Reinmar Koszuliński

        > What i will say however is that i just don;t need the vast majority of the functionality that i saw in every “off the shelf” editor i found!

        > How many functions does the average user use? Around 10-20….

        Hm… But as I wrote – it is possible to build a CKEditor package with just those you need (I guess you haven’t looked into WYSIWYG editors for a longer time). However, it does not make bigger difference – some really basic features are still broken in native implementations. And if you want to have any guarantee that people will be able to use your system in the way they want, even if they want just 3 functions, you need something better than contenteditable. Of course, thanks to contenteditable, none of the existing editors is perfect… :(

        > And I completely disagree with your conclusion. I don;t come from a web dev background, I come from IT Infrastructure, embedded systems, satellite communications

        So you say that you’ll write a buggy satellite software in order to save bytes? I understand that saving bytes is important, but it has to be reasonable choice. If an editor is an important part of my system I’ll pick the one that works, even if that means additional 150KB (gzipped ofc). There are cases in which I need very limited contenteditable and I could save 120KB of that 150KB, but as I wrote – one needs to know what he’s doing choosing native contenteditable.

        • https://twitter.com/reinmarpl Piotrek Reinmar Koszuliński

          PS. One of the things I learnt is – do not reinvent the wheel unless your new one will be better for your needs. If in your situation (time, skills) you can build a better editor good enough for your needs, then you should. I’m just warning how hard it can be, because I know a lot of people who after weeks or months gave up.

          • http://www.barneyparker.com Barney Parker

            Really, I understand what you;re trying to say, but i am happy with this code, it works as well as i need it to, and hopefully others will find a use. That’s all, nothing more, nothing less…

        • http://www.barneyparker.com Barney Parker

          > Of course, thanks to contenteditable, none of the existing editors is perfect…

          Are you saying CKEditor is full of bugs? Oh dear…..

          Let’s stop the flame war now, it’s childish at best…

          • http://andrewensley.com/ Andrew Ensley

            I haven’t seen a flame war. I’ve only seen a reasonable discussion. I completely agree with you, Barney. This implementation is simple and works “well enough.”

            But I also think Piotrek’s warning is appropriate. There are probably a lot of people who will look at this and say “AWESOME! I can replace 440K of JS with 14 lines of code!” But that’s not what this is.

            It’s a very simple, stripped down editor with no bells or whistles or extensive consideration of compatibility (I’m afraid to see how this works in IE <9). That's perfect for me (and I can handle HTML filtering server-side), but not for everyone.

          • http://www.barneyparker.com Barney Parker

            Thanks Andrew!

            To be honest, no, it wasn’t a flame war, but it was heading in that direction which was not wanted, needed or constructive.
            I find it’s best to nip these things in the bud….

      • http://code.google.com/p/lwrte/ plandem

        doh…formatting…

        I totally agree with guy from CKEditor.

        At first glance, it looks like “wow! wtf with all these bloated WYSIWYG around?!”

        Moreover, some years ago i “reinvented wheel”:
        http://code.google.com/p/lwrte/

        It was quite enough till i had time to support it time from time, but when i had no time for it, i dropped.

        Of course, if you are using it for own personal need only it can be enough, but if you gonna to provide it as ‘service/product/feature/plugin’ for customer of some of your product, then it’s a bad idea. Too many time to test.

        test for each major browser after each update of browser
        test for each operation system for each of major browser
        test for each new release of jquery and any other dependencies

        So i came to next conclusion:
        - for only own needs, use what ever you want
        - for other people, use editor with active community/development or you will waste your time for side supporting

        • http://www.barneyparker.com Barney Parker

          Absolutely agree with your comments. The thing that really surprised me is that there hasn;t been any pressure to standardise the way this feature works. Given that it makes life so much simpler, you would think in this age of web standards that the functionality would be defined propperly and that all browser vendors would implement it well…. it’s not a huge task really, but the workarounds used by plug-ins like CKEditor show that a great deal of effort is needed to make it work propprly.

  • http://www.oddhill.se Adam Gerthel

    Would be neat as a module for Drupal plugged into the WYSIWYG API module

  • http://Website Wagner

    what about ie6? it still is one of the best browsers on xp

  • http://nbrogi.com nbrogi

    That looks wonderful.

    Awesome job!!!

  • http://Website stefi

    A HTML source button would definitely be nice.

  • http://Azumbrunnen.me Azumbrunnen

    Content editable works different on all browsers. Especially formatting. I built a whole cms based on this

  • Pingback: World Simplest HTML5 WYSISYG Inline Editor | We...

  • Pingback: Web Design Digest No.7 (04 — 11 August 2013) | Splashnology.com

  • Pingback: World Simplest HTML5 WYSISYG Inline Editor | Bram.us

  • http://www.milieu.us Chris

    We used *contenteditable* for a barebones CMS for one of our Fortune 500 clients. We were very happy with the results compared to using one of the heavy WYSIWYG editors. In specific, our designers were delighted with a system that prevented the content editors from breaking their layouts.

    You are part of a trend towards simplicity that i’m delighted to see Mr. Parker!

    ~ Chris

    • http://www.barneyparker.com Barney Parker

      Thanks Chris, it’s good to hear of this being used in something high profile! It gives some confidence that it’s worth looking in to!

  • http://bglaz.com southstar

    Just a little nit-picky javascript thing.. I think it’s a good habit to pick up though. You can store `$(this).data(‘role’)` as a variable to save some typing, since it’s reused multiple times. `var role = $(this).data(‘role’)` for example.

    • http://www.barneyparker.com Barney Parker

      Yeah, it’s definitely quicker to type, but i can never decide if it’s ideal, or even best practice to do that. As far as I can see you’re allocating a variable to store a copy of something, when a copy isn’t necessary, only convenient.

      Now I accept there is some argument to say that if it makes it convenient then it’s worth it, however there is a principal with database queries that says you should only request the information you want returned, not * for ‘All Columns’. I kind of feel the same about memory usage, if you don;t need to allocate it, you shouldn’t allocate it….

      On the other hand, maybe that shows my 8-bit past, and i’m getting old!!!! :)

      • http://Website Another Chris

        If you are talking jquery you absolutely want to var your selects when you find yourself making the same select 2 or more times. Otherwise your code is constantly spelunking the in the DOM. So it is a little bit more than convenient, its efficient.

        var $role = $(this).data.(‘role’) is a best practice. The tiny amount of information stored under the var to make this reference will out perform the constant DOM digging created by repeating select statement.

        Also, thanks for this simple little editor.

        • http://www.barneyparker.com Barney Parker

          You know, that’s a really good point! As i said at the top of the article, i’m pretty new to web development, and never really thought about that!
          You learn something new every day!! – Thanks!

  • Pingback: 小伙伴们惊呆了!10行 JavaScript 实现文本编辑器 – 梦想天空(山边小溪) | 查问题

    • http://www.barneyparker.com Barney Parker

      Hi, and Thanks! and my apologies that my Chinese is not good enough to reply natively!

      • http://Website Priyanka

        Hi Barney,

        Nicely explained, I liked this post very much. I’ve tried it in my project, but still want to add some more functionalities such as insert image, add link & attach a file. So I m eager to know when will you include these functionalities to your plug-in.

        • http://www.barneyparker.com Barney Parker

          Priyanka, if you check out the Mozilla Docs link in the article there are really easy functions to add links and images etc. There is quite a bit more that you can do, but my aim was to make this as minimal as possible. Adding the functionality really is trivial once you check out the Mozilla docs…

  • Pingback: 小伙伴们惊呆了!10行 JavaScript 实现文本编辑器 | 天天三国杀

  • http://Website Gallien LABEYRIE

    Is it possible to load HTML formatted text dynamically with JS into editor’s div ?
    I tried unsuccessfully, It displays tags as plain text…. :(
    Any idea perhaps ?

    • http://www.barneyparker.com Barney Parker

      It should be fine. For example using jQuery you could:
      $('#editor').html('your html here'); and it will put it in the div. Editing is WYSIWYG, so you will see the formatted text which can be edited!

  • http://ignaty.com Ignaty Nikulin

    Wow, this is amazing work!

    One little note, e.preventDefault(); maybe? To prevent page jumping to top?

    Cheers.

    • http://www.barneyparker.com Barney Parker

      Doh! That’s a pretty essential step! I guess it didn’t get noticed in the demo because the demo page is so short….

      I’ll update the code to reflect that!

  • http://Website Kristina

    Hi,
    Found 2 little issues in the demo but they may already be addressed:

    In the demo, if I want to indent the 2nd line of text, it changes the text size.

    If I want to add numbered list formatting to the title line, it always comes up as a bullet point, not a number.

    Thanks!

    • http://www.barneyparker.com Barney Parker

      Yeah, there’s a few weird situations that seem to crop up, and this little code is definitely not prefect by any means!

      I’ve not found any specific fixes, potentially using the CSS option (check out the MDN link in the article) could fix it…

  • http://Website Charles

    what is the use case for an inline editor without actually editing the source on the server?
    how would you save/store/write the edits?

    • http://www.barneyparker.com Barney Parker

      ultimately you would need to add some functionality to get it sent over to the server.

      The way I have been using it is to have a hidden textarea. If you add an event handler for the ‘input’ event, and copy the contents of the #editor div in to it’s value, you have the exact HTML code available as form input.

      not a perfect solution, but seems to work pretty reliably…

  • Pingback: 小伙伴们惊呆了!10行 JavaScript 实现文本编辑器 – 梦想天空(山边小溪) | Shmily Blog

  • http://Website Paulo

    nice work.
    i got one comment only and it related to your page rendering on ipad mini.
    it is all broken specially the tags containers.

    • http://www.barneyparker.com Barney Parker

      Really? If you could send me a screenshot i’d really appreciate it. Unfortunately I don’t have access to an iPad mini…

  • http://www.coherentsolutions.com/ Coherent Solutions

    Barney, thank you so much for such an easy and helpful explanation!

    • http://www.barneyparker.com Barney Parker

      No problem, I hope it’s useful to you!

  • http://www.brentc.net B

    Hi

    I like this, thanks, even given the points about cross-browser and features. It’s the sort of thing or concept I might one day put in my very fledgling editor effort (http://brentc.net/articles/editor.html), as a nice light option, perhaps also optionally including full package wysiwyg editors if needed. I did get a button working to switch between contenteditable/source there if it’s useful 2 anyone.

    • http://www.barneyparker.com Barney Parker

      I’d certainly be interested to see your code, I’m hoping to do a follow up article soon including many of the comments people have suggested, and that sounds great!

      • http://www.brentc.net B

        Cool- http://brentc.net/js/edit.js (it’s not particularly robust or cross-browser though, suggest firefox). The idea is to add just the script file and a link on a page calling addEditjs() that then adds the editor controls on the page.

        Source/text toggling seemed quite straighforward by changing the editor div to a textarea with a value of the editor’s html content or setting editor ‘s html content to the value of the textarea respectively.

        Otherwise there’s some localstorage use for temporary saving, and I wanted to be able to properly save a file locally, but that needed server side php.

  • http://Website lorenzo

    I’d love to see it without JQuery and Bootstrap

    • http://www.barneyparker.com Barney Parker

      There’s not a huge difference by removing either, there’s so little code anyway that the JavaScript is almost identical. The bootstrap section really should be reduced to just font-awesome, it’s really only the fonts that are necessary for the buttons (although bootstrap makes grouping buttons easier….)

  • Pingback: World Simplest HTML5 WYSISYG Inline Editor Yoann's Place

  • Pingback: From the Bookmarks Bar – August 16, 2013 | Ray Kuhnell

  • http://Website Ashutosh Mahto

    Its a nice article for starting with a simple text formatting editor. Thanks for coming up with this. :)

    I have recently worked on creating a WYSIWYG editor using contentEditable, and I realized it’s not as easy as it looks. :)

    If it’s a simple text formatting editor, it’s good, we can go for it. But, when we start working with ranges, selection and there are many more things which depend upon the development context like image insertion, alignment etc, we end up with lots of patches. Frustration grows when we check it for working cross browser, specially in IE and it’s lower versions than 9.

    And as Piotrek has mentioned “Every single feature which is related to selection, DOM operations, contenteditable and HTML processing is complicated.” I had to write many extra lines of code to make a check for specific browser , then patching the functionality.

    So, for simple text editor it a very nice approach, as it’s lightweight too.

    • http://www.barneyparker.com Barney Parker

      Well put, and I absolutely agree. If you try to implement anything other than the basics, it quickly becomes quite a complex nightmare!
      As Piotrek pointed out, there are waaay too many browser differences to make it practical, but as you say, for simple text editing it’s an absolutely ideal option!
      It also makes sense when it’s for an internal app, where you can be certain of the browser which is going to be used.

  • http://Website Anthony

    This is nice. Thanks.

    One minor UX issue, on the sub-script and super-script buttons.

    Once you super or sub a piece of text, it’s impossible to get it back to normal. It’s stuck. Clicking the button a second time should make any selected text normal again.

    • http://www.barneyparker.com Barney Parker

      You’re right, and I’ve not found a way around it! I guess there are a few items that are to be avoided. I think a nice idea may be to try it out in each different browser, and try to get an entry in something like Quirksmode…

  • http://Website CLaFarge

    What would you use if you required the ability to insert images and tables?… ’cause I do :(

    • http://www.barneyparker.com Barney Parker

      Hi there! If you check out the link to the Mozilla Developer Network in the article there are few items i didn’t include in the code of this article, and inserting images is one of them!

      i was going for the most minimal editor i could so i left it out because you need to upload the image etc.

      WordPress has an interesting method of handling this, essentially an image needs to be in “the Library” before you can insert it. The work around is that if it’s not in the library, you can get an overlay which allows upload to the library, and once you’re done it’s available to insert! (does that all make sense?)

  • Pingback: Worlds simplest HTML5 WYSIWYG Editor | Web Developer Blog

  • Pingback: World Simplest HTML5 WYSISYG Inline Editor | Ba...

  • Pingback: Geek Links #2 | Radii Production

  • Pingback: Links from the summer | developer52

  • http://newpanda.com bob

    First of all you people (especially you, Barney) are all much smarter than me (i’m just the dumb ceo/sales-guy type), but I’m on a quest to find:

    a) a simple, light editor to use in our app for “snippets” within a master content template/message. Meaning, for our eNewsletter product, I need our users to be able to click into just one small part of the master template (like an article) and have editing tools presented. Currently, they have control of the entire content/HTML within the Editor and lots of bad things can happen! We currently (don’t laugh) use mostly Telerik products, including their editor. I think your solution, Barney, looks awesome for this one.

    b) to further control (make easier) the environment, I am also looking for a drag & drop solution, where we could show a list of our “TAGS” (which are elements containing images, text, table, etc in HTML) and the user would be able to click the snippet and drag it anywhere into the main HTML Editor. For this project, I’m assuming we would need to use a more feature-rich editor (where the user can upload/manage images, build tables, etc). QUESTION: what is the best solution out there? I am pushing our developers to abandon Telerik/asp.net and move to bootstrap/HTML5, CSS3 and open-source-based solutions. Barney, I see that you’ve researched a lot! Can you point me in the right direction? Think MadMimi and MailChimp’s drag & drop / editing features. Anyone else have input? Any suggestions would be really appreciated!

  • http://blingee.com/profile/shakejuice99 blingee.com

    Hi there, I do believe your web site may be having browser compatibility issues.
    Whenever I take a look at your blog in Safari, it looks fine however, if opening in IE, it
    has some overlapping issues. I just wanted to provide you with a
    quick heads up! Apart from that, great blog!

    • http://www.barneyparker.com Barney Parker

      Thanks for that, i’ll see what i can do….. :)

  • http://www.xn--hc0bu4i9oo30f.kr/community2/5934 Testoril Energy

    Good post. I learn something new and challenging
    on blogs I stumbleupon everyday. It will always be helpful
    to read through content from other authors and use something from their sites.

  • http://www.fnatic.com/users/YolannodozaSiti http://www.fnatic.com

    Fascinating blog! Is your theme custom made or did you download it from somewhere?
    A theme like yours with a few simple tweeks would really make my blog stand out.

    Please let me know where you got your theme.
    Bless you

    • http://www.barneyparker.com Barney Parker

      to be honest, not a clue! when i first set up the blog i seached around for a simple and clean template, but as to where it came from, i really don’t remember, sorry…

  • http://clinica-cirurgia-plastica.org/ visite

    I think everything composed made a lot of sense.
    However, think about this, what if you added a little information?

    I ain’t saying your information isn’t good., however what if you
    added something that makes people want more?
    I mean World Simplest HTML5 WYSISYG Inline Editor | Barney Parker is a little vanilla.
    You might peek at Yahoo’s home page and see how they create article titles to grab viewers to open the links.
    You might add a video or a picture or two to get readers excited about
    what you’ve got to say. In my opinion, it might bring your posts a little bit more interesting.

    • http://www.barneyparker.com Barney Parker

      yeah…. um…. you ever visited Yahoo’s home page? Anyone ever visit Yahoo’s home page since like 1998? Seriously, Take a look. It looks like came from 2004… are they seriously still in business? I guess there must be some degree of temporal loyalty associated with any domain name….

  • Pingback: Worlds Simplest HTML Markdown Editor | Barney Parker

  • http://hypothyroidismsymptoms.info Hypothyroidism Symptoms

    Your style is so unique in comparison to other people I’ve read stuff
    from. Thanks for posting when you’ve got the opportunity, Guess
    I’ll just bookmark this web site.

  • http://Website Kevlar Tactical Gloves

    It’s actually a cool and helpful piece of information. I am glad that you just shared this helpful information with us. Please keep us informed like this. Thank you for sharing.
    :) #$# :(

  • http://point.md click here

    9daQmy Very neat blog article.Really thank you! Awesome.

  • Elodia Pacini

    I simply want to tell you that I’m all new to weblog and certainly loved this web-site. Probably I’m planning to bookmark your website . You actually have beneficial articles and reviews. Thanks a bunch for sharing your blog.

  • http://Website Grace

    You, sir, are a -god-. I’ve been chugging away at writing my own lightweight editor for a project for the last few hours and I just about threw in the towel when Google finally landed on this gem. :) Internet brownie points for you!

    • http://www.barneyparker.com Barney Parker

      Thanks Grace, glad to be of service! I will point out though, there are problems with the whole scheme, as many of the comments point out. In the end i opted for using a MarkDown editor. way simpler, pure text, but great formatting, plus, it just makes sense when you use it! Check out: http://www.barneyparker.com/worlds-simplest-html-markdown-editor/

  • http://www.compusam.com compusam

    -If you put this code, the page don´t refresh and don´t move up.

    <a data-role='undo' href='javascript:void(0)'>
    <a data-role='redo' href=
    'javascript:void(0)'>
    <a data-role='bold' href=
    'javascript:void(0)'>

    • http://www.barneyparker.com Barney Parker

      Good call Compusam!!! I’ll add that to the pen!

  • http://stackoverflow.com/users/610573/chris Chris Baker

    I was planning on using this for an ultra-simple inline html editor. I see you’ve moved off to Markdown… I am not sure I want to make my target users learn about Markdown. I scrolled through the comments, and I didn’t see any major comparability issues, yet you mention that there were some. What were the dealbreakers? I guess I’m asking you to talk me out of doing this :)

  • http://Website matt

    I notice that the h1 and h2 seems to break if you have the cursor in the text of a list item. The text just keeps getting bigger and bigger.

    Steps to reproduce:
    1enter some text
    2make it a list item by pressing the ordered or unordered list button
    3place the cursor at the beginning of the text
    4press the h1 or h2 buttons
    5 repeat 4, and the text gets bigger, the expected result is that it should go back to previous size.

  • http://www.crork.com check this out

    QjD392 Major thanks for the blog post.Thanks Again. Awesome.

  • http://Website Elijah Fowler

    There’s a better way to go about canceling the link’s native behavior than to put “href=’javascript:void(0)’” on every link. You can see my Codepen example here.

    Also, working on a solution to fix the Normalize bug with superscript and subscript.

    Great article though!

  • javiertroya

    The problem of href javascript:void(0) can be solved by capturing the event in the function and setting the preventDefault() function like this

    $(‘#editControls a’).click(function(e){
    e.preventDefault();

    //rest of the code
    })

    Is better and is the right way to do it with jQuery

  • http://www.eurobytes.nl/ blade19899

    i changed the

    This is just some example text to start us off

    to

    This is just some example text to start us off

    But when i do that it doesn’t work anymore. Am trying to save my changes using form and php. I was searching in the js, file for the ?div#editor? part to change it in ?textarea#editor? so i could get it working, but can’t seem to find it.

    How can i make the World Simplest HTML5 WYSISYG Inline Editor work with textarea?

    • Barney Parker

      @blade1989:disqus the reason it wont work is because the contenteditable attribute only works (ironically) on a tag that isn’t already editable!

      The way I got around this was to add an onchange javascript function to the div and have it copy the entire contents of the contenteditable in to a textarea. This textarea can be hidden from view, so from the users point of view, they are working entirely within the contenteditable div, but from a forms point of view, it’s just a standard textarea.

      One nice side effect is that if you leave it visible during development, you can see the html that gets produced. The downside is that unfortunately all browsers seems to do the html differently…..

      • http://www.eurobytes.nl/ blade19899

        My js is pretty basic. Do you think you can post an example code I can use? That would be much appreciated!!!

        • http://www.barneyparker.com Barney Parker

          @blade19899 I have updated the codepen example at http://codepen.io/barney-parker/pen/idjCG however the basic idea is this:

          Create a textarea with a name (#output for example)

          create a function that does the copy from the #editor div to the #output textarea.

          function update_output() {
          $(‘#output’).val($(‘#editor’).html());
          }

          Then you need to bind a set of potential events on the #editor:

          $(‘#editor’).bind(‘blur keyup paste copy cut mouseup’, function(e) {
          update_output();
          })

          and also remember to call the update_output() function on the button clicks too

          Feel free to take a look at the codepen, it shows it working and it’s good to have a play with in a few browsers to see if it truly fits your needs