[shadow-styling] matching rules for complex selectors beginning with :host and :ancestor

The spec here:

http://dev.w3.org/csswg/shadow-styling/#host-selector
http://dev.w3.org/csswg/shadow-styling/#ancestor-selector

does not match my understanding of how these features were originally
envisioned. Specifically, as mentioned in the spec in section 5.3 example
6, an author wants to be able style elements in shadowRoot conditionally
based on how the host or an ancestor of the host is styled. This not only
allows for a type of theming, but also allows other types of styling based
on other external conditions. For example:

 * a menu-item that looks one way when it's inside a menu and another way
inside a popup-menu.
 * a list-item that has an icon inside it that lights up when the list-item
itself has a "selected" class.
 * an input type element that has special internal styling when it's host
element has a `disabled` attribute.

As currently spec'd, it looks like :ancestor should be useful for some of
this, but it doesn't work for styling that's influenced only by the host
element.

When proposed, my understanding of :ancestor was that it would be
*identical* to :host except that the argument in the parens could match
anywhere in the element's lineage (precisely as is defined in the spec now).

If that's the case, then all styling that needs to 'connect' with an
outside scope is done via combinators like this:

 /* match an input that is a child of the shadowRoot IFF the host element
matches .special */
:host(.special) > input { ... }

 /* match an input that is a descendant of the shadowRoot IFF one of the
host's ancestors matches .special */
:ancestor(.pretty) .pony { ... }

I think this basic approach is much cleaner than the currently spec'd
behavior of :ancestor. You always use standard combinators rather than
needing the new concept introduced in the currently spec'd :ancestor.

This behavior also matches what is currently implemented in Blink (turn on
experimental web platform features in Chrome Canary before trying these):

:host combinators: http://jsbin.com/rijaviki/1/edit
:ancestor combinators: http://jsbin.com/hudepodi/1/edit

We may have some options here around exactly how complex selectors work
with :host/:ancestor, but what is implemented today in Blink provides a
consistent model. For example, consider

:host > input

This styles an input inside the host's shadowRoot. This has the advantage
of allowing per-shadowRoot styling since the style element is connected
with a specific shadowRoot. If instead this matched the light dom, we would
have a disjointed mental model around distribution. The author would be
forced to "locate" the element twice, once in the content select attribute
and once in the :host selector. Instead, we disallow this an require the
use of /content/ to select elements in the host's 'light dom'.

Received on Thursday, 13 March 2014 00:39:37 UTC