Setting the caret position to an empty node inside a contentEditable element

I found a workaround for Webkit, don't know if anybody found this before but instead of programmatically appending a zero-width space, you can do the same thing with the css3 content property in the after psuedo-selector of the elements you want to put the caret in. This has the advantage that the extra characters don't show up in the DOM and the user can't navigate the caret between it. So basically it doesn't need cleaning up.

For this to work for any child element of your content editable element it would be something like this:

#mycontenteditableelement *:after {
    content: '\200B';
}

I didn't check completely, but I suspect this is a full workaround.


IE's selection/range model is based around indexes into text content, disregarding element boundaries. I believe it may be impossible to set the input focus inside an inline element with no text in it. Certainly with your example I cannot set focus inside the last element by clicking or arrow keys.

It almost works if you set each span to display: block, though there's still some highly strange behaviour, dependent on the existence of whitespace in the parent. Hacking the display to look inline with tricks like float, inline-block and absolute position make IE treat each element as a separate editing box. Relative-positioned block elements next to each other work, but that's probably impractical.

If it makes you feel any better, IE9 finally fixes this unpleasantness and adopts the standard range model. (Hooray!)

it's acceptable to have whitespace in the last node if the caret is at the very start.

I'd probably do that, then, unless an IE selection expert can think of anything better. (Calling Tim Down!)


Set the element's innerHTML to a zero-width character:

('element').innerHTML = '&#200B';

Now the carret can go there.