::Parts of cats and hats everywhere, slashed by shadow

Sure it's a tad long - but you're a champ, you'll deal.

Yesterday a group of folks from this thread convened for a face-to-face
meeting. I'd like to summarize the discussion, review our options, and
present why I believe the proposal we zeroed in on during our meeting is
the correct one:

A little history from the other side of the shadow coin --> the JS DOM. A
long time ago in a galaxy far away, there was a feeling we should
security-encapsulate Shadow DOM - it was a noble pursuit, a courageous
endeavor. After a few cycles with the specs it became imminently clear that
security-encapsulation of Shadow DOM is fraught with significant problems,
and the added constraints only made possible a small number of all total
use-cases. As a result, the decision was made to instead provide a flavor
of encapsulation that shielded non-explicit Shadow DOM access and style
overwriting. This form of encapsulation covers the vast majority of
use-cases - primarily the desire for devs to create custom elements that
provide a stable interface/render that isn't corrupted by unintended DOM
manipulation and style leakage. However, an important allowance was the
ability for component consumers to explicitly access the Shadow DOM
via the *shadowRoot
*property. This provided a way for developers to knowingly, explicitly
reach into a component and manipulate its DOM - something that is often
essential for consumers of third-party code.

Why talk about the JavaScript interface portion of Shadow DOM in a debate
over a style issue? Because new web platform technologies that introduce
APIs across layers of the stack are usually at their best when they are
*symmetrical*, *predictable*, and *familiar*.

Let's take a look at the three proposals for styling elements in the Shadow
DOM --> ::part, cat/hat (^^/^), and an extensible combinator +
*shadow*token (/shadow)

 *1)** We should ::part ways*

On its face, the notion of hoisting specific elements into CSS user-space
seems like a good idea. You give component developers an explicit API for
exposing named pieces of encapsulated shadow elements, and users get
meaningful names to use in styling those elements. Unfortunately, this idea
introduces a few major issues:

   1. The component author is tasked with explicitly marking elements
   within their component they wish to expose for styling
   2. As a component consumer, you must know and use the special name for
   each element the component author marks
   3. If the component developer forgets or fails to provide a token for a
   particular shadowed element, third-party developers are left without any
   easy path to accomplish their styling goals
   4. In real world use, shadowed element tokens become numerous, verbose,
   and crufty.

Assessment: this proposal requires writing selectors that are *not familiar*,
using tokens that are *unpredictable*, and it is certainly *not symmetrical
*to the JS DOM encapsulation paradigm.


*2)** Hats ^, and cats ^^, and bears - oh my!*

Cat-hats are on the right track. This idea turns (correctly) toward a more
open and permissive model. Moving to a known combinator allows component
consumers to explicitly, with intention, style anything in the Shadow DOM.
This means component consumers are no longer left to hope that authors
provide the styling hooks they need. It also removes the need to litter CSS
code with shadow element tokens. In addition, component consumers are still
able to style shadowed elements in a more familiar way. Awesome, problem
solved!...close, but no cigar. Here's what this option leaves to be desired:

   1. It introduces YAACs (Yet Another ASCII Character) - pretty soon we'll
   need a periodic table to remember them all
   2. YAACs are as good as klingon to novice developers - shouldn't we be
   more obvious if we can?

Assessment: this proposal is pretty darn close - it allows the use of
*familiar* looking selectors, it's *predictable* once you understand the
combinator, and *symmetrical* to the JS DOM encapsulation paradigm.

Example: *x-foo ^ div*


*3)** /shadow games FTW!*

An extensible combinator is the gift that keeps on giving. With an
extensible combinator (ex: / + a token) we can define tokens like *shadow*,
and *shadow-all, *to enable the styling of shadowed elements*.* The best
part is we can introduce other tokens in the future without YAACing on our
shoes. This proposal brings with it all the positives that hat-wearing cats
deliver, without the downside of two new, non-obvious, ASCII combinators
that are hard-bound to a specific DOM API. The only negative I can think of
currently:

   1. */shadow *is longer than *^*

Assessment: this proposal hits on all cylinders - it allows users to write
*familiar* selectors without knowing one-off token names, provides a
*predictable* flow for shadow element styling, and is *symmetrical* to the
JS DOM encapsulation paradigm.

Example: *x-foo /shadow div*

-----

Tab is working on a draft for the extensible combinator proposal as we
speak - in the meantime, any thoughts?


Daniel J. Buchner
Product Manager, Developer Ecosystem
Mozilla Corporation

Received on Friday, 7 February 2014 17:44:30 UTC