Re: Need a better way to reach into the shadow DOM subtree

On Mon, Apr 11, 2011 at 12:50 PM, Dimitri Glazkov <dglazkov@google.com> wrote:
> Folks,
>
> We really need to have a better way to address elements inside a
> shadow DOM subtree. The pseudo-element doohickey is deficient,
> because... well, it's a pseudo-element.

A more complete description of the problem:

Under XBL2/Components, elements can have a shadow tree - DOM nodes
that are hidden from normal sight, but used to construct the rendering
of the element.  For example, form controls can be viewed as having a
shadow tree, exposed via pseudoelements (the proposed ::text or
::value pseudoelem on <input type=text).  So can complex elements like
<video controls> - the controls are all DOM nodes living the shadow
tree (literally, now, in Webkit trunk).

Component authors would like to expose pieces of the shadow DOM to CSS
directly, so authors can style those bits without having to know about
the rest of the shadow DOM.

We can possibly do this simply through pseudoelements, like we do
currently, such as video::timeline.  The current restrictions on
Selectors, though, prevent us from treating pseudo-elements as
first-class citizens, and selecting them based on other information,
like pseudoclasses.

So, for one, we'd like to be able to put more stuff after a pseudo-element.


Further, though, shadow nodes may have further structure.  A shadow
node may, itself, be a component, for example, and thus expose a
nested shadow tree.  Imagine a video timeline control was implemented
simply as an <input type=range>, for example - to style the thumb on
the range, you want to select the timeline (in the video's shadow) and
then select the thumb (in the the timeline's shadow).

This can possibly be done just by chaining the pseudoelements, like so:

video::timeline::thumb

However, that gets ugly fast, particularly if pseudoclasses are thrown
into the mix:

video:nth-child(2)::timeline:enabled::thumb:pressed

I don't know about you, but the above selector is basically gibberish
to me.  Imagine these were all real elements instead:

video:nth-child(2) > timeline:enabled > thumb:pressed

That's much much better - the whitespace around the combinators breaks
up the selector into good logical chunks.  I'd prefer if we can
somehow retain this readability benefit when selecting into shadow
trees.

My first instinct is to just add a new combinator, maybe "A % B", that
selects a node B that lives in the shadow tree of A.  Using this you'd
write out:

video:nth-child(2) % timeline:enabled % thumb:pressed

(To answer Hyatt's comment directly - this wouldn't allow arbitrary
selection into a shadow.  The component author still has to explicitly
expose certain nodes as shadow nodes before the selector engine would
pick them up.)

It's possible that the correct answer to this case is that Components
should have some way of flattening their tree of shadows, so you could
just select the thumb directly from the video, but that doesn't seem
like quite the right answer.  It means you can't distinguish thumbs
that are exposed by different shadow nodes, and also means that you
can't select a thumb based on the state of the timeline (like whether
it's :enabled or :disabled).

~TJ

Received on Monday, 11 April 2011 20:20:24 UTC