[css3-text] Suppressing underlines propagated from ancestors

Use case: suppose you're writing a rich-text editor in HTML+CSS,
perhaps using contenteditable and execCommand() and such.  There's
some markup in the document like this:

<p style="text-decoration: underline">Hello there!</p>

The user has "there" selected and presses the underline button in your
editor.  They expect the underline to disappear.  What happens?  You
can test your favorite browser's execCommand() implementation with the
following code:

data:text/html,<!doctype html>
<button onclick="execCommand('underline', false, null)"><u>U</u></button>
<div contenteditable=true>
<p style="text-decoration: underline">Hello there!
</div>

* IE 9 RC and Firefox 4b11 give up and do nothing
* Chrome dev converts to <p><u>Hello </u>there<u>!</p>
* Opera 11 converts to <p style="text-decoration: underline">Hello
<u>there</u>!</p>, which seems like a bug

So only Chrome (WebKit) actually behaves as the user expects.  It can
only do this by considerable DOM surgery, making up and reorganizing
elements.  If you make it a bit harder, Chrome fails too.  Like here:

data:text/html,<!doctype html>
<button onclick="execCommand('underline', false, null)"><u>U</u></button>
<div contenteditable=true style="text-decoration: underline">
<p>Hello there!
</div>

Chrome does nothing here, like Firefox, because it doesn't want to
touch the non-contenteditable ancestor.  It's easy to come up with
other cases where all browsers do something wrong, like:

data:text/html,<!doctype html>
<button onclick="execCommand('underline', false, null)"><u>U</u></button>
<div contenteditable=true>
<p style="text-decoration: underline; color: red"><span style="color:
blue">Hello there!</span>
</div>

Chrome dev converts to <p style="color: red"><span style="color:
blue"><u>Hello </u>there<u>!</u></span></p>, which changes the
underline color from red to blue on the remaining text.  Other
browsers just give up, as before.


I'm currently writing a spec for execCommand().  Things like bold and
italic work fine -- if all else fails, just stick in a <span
style="font-weight: normal"> or such.  But for removing underlines,
I'm faced with writing an excessively complicated algorithm that will
fail or behave strangely in some cases.  Instead, I'd like to ask that
some property be added that allows text-decorations from ancestors to
be suppressed.  Possible syntax:

* text-decoration-suppress: underline
* text-decoration: suppress-underline
* text-decoration: no-underline

These would stop the relevant decoration from propagating from
ancestors, without affecting any decorations specified on the element
or its descendants.  So for instance,

<u style="color: red">Abc <span style="text-decoration-suppress:
underline">d<u>e</u>f</span> ghi</u>

would have "Abc ", "e", and " ghi" underlined, but not "d" or "f".  If
you specified "text-decoration: underline; text-decoration-suppress:
underline" on a single element, then any ancestor underline would be
suppressed but the element's own underline would be drawn.  This would
be relevant in a case like this:

<s style="color:red; font-size:2em">Abc <s style="color:blue;
font-size:0.5em; text-decoration-suppress: line-through">def</s>
ghi</s>

where you'd normally have multiple lines drawn in different positions,
so the descendants' lines wouldn't cover the ancestors'.  (WebKit
seems to only draw one line regardless, which seems incorrect per
spec, but anyway makes this behavior irrelevant.  It's relevant for at
least Gecko and Opera.)

Received on Tuesday, 22 February 2011 21:55:01 UTC