[whatwg] Pressing Enter in contenteditable: <p> or <br> or <div>?

Behavior for Enter in contenteditable in current browsers seems to be
as follows:

* IE9 wraps all lines in <p> (including if you start typing in an
empty text box).  If you hit Enter multiple times, it inserts empty
<p>s.  Shift-Enter inserts <br>.
* Firefox 4.0 just uses <br _moz_dirty=""> for Enter and Shift-Enter,
always.  (What's _moz_dirty for?)
* Chrome 12 dev doesn't wrap a line when you start typing, but when
you hit Enter it wraps the new line in a <div>.  Hitting Enter
multiple times outputs <div><br></div>, and Shift-Enter always inserts
<br>.
* Opera 11.10 wraps in <p> like IE, but for blank lines it uses
<p><br></p> instead of just <p></p> (they render the same).

What behavior do we want?

A problem with <p> is that it has top and bottom margins by default,
so hitting Enter once will look like a double line break.  One
real-world execCommand() user I looked at (vBulletin) sets p { margin:
0 } for its rich-text editor for this reason, and translates <p> and
<div> to line breaks on the server side.  The usual convention in text
editors is that hitting Enter only creates one line break, although
Word 2007 seems to do two by default.

Another problem with <p> is that it's very easy to create
unserializable DOMs with it.  I've seen cases where at least some
browsers will put things inside <p> that will break out of the <p>,
and I've done it myself by mistake too.

The problem with <br> is that it's a pain to deal with.  It forces you
to deal with lines as sequences of adjacent sibling nodes instead of
as a single node.  Also, sometimes <br> doesn't do anything, like
(usually) a single <br> at the end of a block box, but when you add
something after it it suddenly starts doing something.  If lines
aren't wrapped in block elements, then whenever you have to move
around some text, you need to be sure that you check that you're not
removing a <br> or failing to move one and thereby running two lines
together, or leaving an extra <br> someplace so there are now two in a
row.  I've seen bugs to this effect in multiple browsers, where they
don't insert a <br> when they should (but behave fine with <div>/<p>),
and have made the mistake a lot myself.

So my current thought is to demarcate lines with <div>s consistently,
only using <br> when there are multiple line breaks in a row.  This is
unlike any current browser, since everyone uses <br> at least for
Shift-Enter.  If this is the way we want to behave, then I'll also
have commands normalize nearby <br>s to <div>s where it makes things
easier, like I normalize other types of markup.

Feedback appreciated.

Received on Thursday, 12 May 2011 13:28:47 UTC