Re: [WICG/webcomponents] Web components should be able to easily adapt to the host page while maintaining enapsulation (Issue #986)

> Some thoughts & questions (adapted from [mastodon discussion](https://front-end.social/@AmeliaBR/109938668078829176)):
> 
> * IMO, there should be two-way opt-in for style crossover. The web component author would need to explicitly pull in external styles in the CSS, or somehow make the elements visible to external selectors (with element attributes or settings used when adding the shadow tree). But the page author should also need to enable the style crossover, either with an attribute on the embedding custom element, or a JS option when registering the custom element class. (Either of which is still a lot easier than re-writing your full stylesheets to use custom properties or ::part selectors.)  For nested web components, there would need to be opt-in all the way up the tree.

I strongly disagree. 
- If a component is written assuming form controls get styles from the surrounding page, it would not work well without that. As a WC author, you don't want to write even more code to account for both cases. 
- What happens when the attribute is used externally, but the component doesn't use the corresponding attribute internally? Poor DX.
- It also increases the boilerplate authors have to write to use the element.
- This means that in practice this attribute wouldn't be used, and developers would instead do things such as @DarkWiiPlayer described of pulling in all styles from the shadow host. 

As a WC author, you want your component to Just Work™, without people using it having to jump through hoops. It's far preferable to shift complexity to the component internals, than outwards to the component consumer.

> * Selectors are used for more than just style rule matching. Is there a benefit or risk in also opting-in to visibility for `querySelector` (and similar)?

I don't see the point. WIth open shadow roots, authors can always access whatever they want through `element.shadowRoot`, so this adds extra complexity without really serving any more use cases.

> * Is it enough to just say that, for example `<button>` within the shadow tree should match a `button` selector from the light(er) DOM, or should there be a way to say that `<my-button>` (that is, a nested custom element) or a `<div role="button">` should appear to be a button for the purpose of the host document's stylesheets?

That's a good point, and indeed a syntax that allows for this too would be great. Though I worry that trying to cater to those use cases as well would overcomplicate this, or prevent the syntax from catering to other use cases (e.g. one can imagine a syntax where you explicitly specify what element types and attributes you want this to match as, but then you lose combinators etc). I'd also imagine that having a `<my-button>` that does selector matching as a `<button>` would be rather complex to implement.

> * This feature needs to avoid naming clashes for classes and data-attributes (i.e., the same class name used in the external page for a different meaning than how it is used by the web component author; this is the main reason for wanting encapsulation of stylesheets). But for the proposal to be useful, it would need to support a full set of selectors based on HTML semantics (type attribute, aria, pseudoclass / pseudoelement). Is it realistic to define a global allowlist / blocklist of visible attributes? Or would the web component author need to configure this somehow?

This is why my proposal was to exclude certain "userland" attributes from matching. We definitely don't want to be maintaining allowlists of attributes in the spec though, that's a recipe for disaster.
Not sure all pseudo-classes would be useful, e.g. `:nth-child()` would reveal things about the element's position in the DOM that you may want to encapsulate. That's why I proposed specific categories of pseudo-classes. I should also add [input pseudos](https://drafts.csswg.org/selectors/#input-pseudos).
Pseudo-elements would be useful too, e.g. you probably want things like `::placeholder`, `::selection` etc.

>   Similarly: lots of typographic and form styles depend on sibling or parent/child relationships, so you'd want to support complex selectors. But this breaks the encapsulation of the shadow DOM tree, and could create brittle dependencies where an extra wrapping div or span, or a nested web component or slot element, would throw off the styles.

Per my original proposal, combinators would match as long as all the elements involved were exposed. E.g. `details > summary` would match as long as *both* `<details>` and `<summary>` were opted in through this attribute.

> * I know there has been some spec discussion related to other named items in stylesheets (imported fonts, animation keyframes, and custom properties) and how they are interpreted when styles inherit across shadow boundaries. I don't know whether that's all been specified yet, but this would make it all the more urgent that it is cleared up in a way that avoids unintentional name clashes.

Ah, that's a good point, right now these are tree scoped, i.e. animations from the outside do not trickle in.
I don't see an obvious way to resolve this without pulling in all the names (which is what `open-stylable` would do).
Though I think even if they continue to be private, there's usefulness in this.

> * How would / should the CSS cascade combine shadow/light(er) DOM style rules on a single element? Do the existing rules around slotted and host pseudo selectors make sense if generalized, or would additional cascade rules be required?
> * Do existing rules about selector matching (on light and shadow DOM trees separately) vs style inheritance (on the slotted tree) still make sense for the desired use cases?

Not sure what you mean in either of these questions.

> To answer many of these questions, it would help to have a collection of use cases for web components with a mix of slotted and templated elements where styling should be harmonized with the parent document, and examples of how WC authors are currently handling it (by building up templates all in the light DOM, or by copying stylesheets into the shadow DOM, or using complex custom props systems, or ???).

Good point, I'll try to gather some. FWIW what prompted this was me writing a component for image input (that supported both linking, uploading, pasting etc) and I wished the input and button could automatically get styling from the host page.

I think the way most WC libraries deal with it is that they include their own core styles, and try to offer parts and custom properties liberally, for customization. Which of course means a lot of integration effort for the WC consumer.


-- 
Reply to this email directly or view it on GitHub:
https://github.com/WICG/webcomponents/issues/986#issuecomment-1448773957

You are receiving this because you are subscribed to this thread.

Message ID: <WICG/webcomponents/issues/986/1448773957@github.com>

Received on Tuesday, 28 February 2023 19:51:02 UTC