WICG / webcomponents

Web Components specifications
Other
4.34k stars 371 forks source link

[open-stylable] Collection of user stories #1052

Open michaelwarren1106 opened 3 months ago

michaelwarren1106 commented 3 months ago

Let’s let this issue serve as the single place to collect user stories around the “open-stylable shadow roots” proposal.

https://github.com/WICG/webcomponents/issues/909

Submit user stories as comments and I will do my best to collate theme here in this top comment for easy viewing/referral.

User Stories

mayank99 commented 3 months ago

Pasting my comment:

  • "As a component author, I want to build unstyled components that only manage behavior. I want to give my consumers full control and achieve maximum compatibility with their existing styling solutions. I am ok with the tradeoff that DOM changes can break consumer's styles."
  • "As a website author, I want to use shadow DOM for my own components (that I author and consume myself). I want to use my existing CSS system, including any global resets, utility classes, and hand-rolled scoped classes. Crucially, I want these styles to be usable in DSD without causing FOUC."
robglidden commented 3 months ago

From shadow layers proposal (noting they may be a bit over-broad particularly as to coordination scenarios):

Use Cases Addressed

michaelwarren1106 commented 3 months ago

From shadow layers proposal (noting they may be a bit over-broad particularly as to coordination scenarios):

Use Cases Addressed

  • Include all document CSS as a low priority layer inside a shadow tree. This is the heart of a solution to the original issue as opened.
  • Support both declarative and imperative use. Declarative shadow trees are fully supported from the onset, as well as imperative use cases.
  • Include selected document CSS as a layer inside a shadow tree. Selected named outer layers can be brought into a shadow tree by either a shadow tree designer or shadow tree user.
  • Enable layer reprioritization. Inner and outer context layers can be intermixed and reprioritized.
  • Enable shadow tree designers to bring in document CSS without intervention by a shadow tree user. If desired, a shadow tree designer can bring in all of or just selected layers of the document outer context CSS, without intervention of the shadow tree user.
  • Enable coordination between shadow tree designers and shadow tree users. Either can bring in and repriortize outer layers.
  • Enable shadow tree user to add and repriortize layers originally provided by shadow tree designer. A user can bring in any chosen outer layer, not just those pre-defined by a designer.
  • Enable a shadow tree designer to "advertise" to shadow tree users the CSS priorities of a shadow tree's inner context. A designer can expose, publish, or document the original layer order of a shadow tree, so that a user can knowingly adjust it or add to it.
  • Polyfillable. As hopefully implied by this proof of concept implementations.

these are great! would you mind taking a swing at framing these use cases in terms of user stories? i definitely agree that any solution must have some/or all of these baked in, but the current phrasing makes them sound more like features of a solution and less like stories that describe particular, specific user needs/wants.

robglidden commented 3 months ago

Filtering as a potentially key requirement:

To me, the key open question that needs to be answered is whether selective adoption of document-level stylesheets is necessary or not. That is, should a component or users of the component need to be able to filter (i.e. selectively apply) which stylesheet or style rules apply to its shadow tree.

answering yes, filtering needed, with related essential requirements:

Use cases are intertwined.

Whether simple (I just want my page resets to work in my shadow tree) or most painful (component and context are controlled by different entities) or in between, use cases trace to the same shadow encapsulation, and loosening encapsulation will likely impact many if not all in some way.

Declarative shadow DOM is required.

To me, declarative shadow DOM is required from the onset not just because it is a new thing so logically it must be supported too, but because shadow trees are just HTML and they are what are doing the encapsulating to loosen. And they are a part of the solution.

So Javascript-only solutions are basically out. And polyfillability though not a strict requirement is in this case something of an acid test for completeness.

But also declarative shadow trees already by design address opt-in for imperatively-created web components.

Context-aware opt-in protection is needed.

I don't think an opt-in flag or mode that just brings in all page styles would work as expected in all cases. Some shadow styles could unexpectedly lose. Or get pulled back into a specificity race that could feel like shadow trees just gave up.

Prioritization is required.

Or maybe just unavoidable, since unlayered styles are of necessity assigned a layer priority. And a limited form of priority for shadow trees already exists in the context step, so any brought-in styles would pass through that step too.

rniwa commented 3 months ago

Declarative shadow DOM is required.

To me, declarative shadow DOM is required from the onset not just because it is a new thing so logically it must be supported too, but because shadow trees are just HTML and they are what are doing the encapsulating to loosen. And they are a part of the solution.

So Javascript-only solutions are basically out. And polyfillability though not a strict requirement is in this case something of an acid test for completeness.

What are concrete user scenarios that necessitates declarative shadow DOM support? i.e. what exactly is one building to encounter this need?

Context-aware opt-in protection is needed.

I don't think an opt-in flag or mode that just brings in all page styles would work as expected in all cases. Some shadow styles could unexpectedly lose. Or get pulled back into a specificity race that could feel like shadow trees just gave up.

Again, what are concrete user scenarios that necessitates context-aware opt-in?

Prioritization is required.

Or maybe just unavoidable, since unlayered styles are of necessity assigned a layer priority. And a limited form of priority for shadow trees already exists in the context step, so any brought-in styles would pass through that step too.

Again, what are concrete user scenarios that necessitates prioritization of CSS rules?

michaelwarren1106 commented 3 months ago

Filtering as a potentially key requirement:

To me, the key open question that needs to be answered is whether selective adoption of document-level stylesheets is necessary or not. That is, should a component or users of the component need to be able to filter (i.e. selectively apply) which stylesheet or style rules apply to its shadow tree.

answering yes, filtering needed, with related essential requirements:

Use cases are intertwined.

Whether simple (I just want my page resets to work in my shadow tree) or most painful (component and context are controlled by different entities) or in between, use cases trace to the same shadow encapsulation, and loosening encapsulation will likely impact many if not all in some way.

Declarative shadow DOM is required.

To me, declarative shadow DOM is required from the onset not just because it is a new thing so logically it must be supported too, but because shadow trees are just HTML and they are what are doing the encapsulating to loosen. And they are a part of the solution.

So Javascript-only solutions are basically out. And polyfillability though not a strict requirement is in this case something of an acid test for completeness.

But also declarative shadow trees already by design address opt-in for imperatively-created web components.

Context-aware opt-in protection is needed.

I don't think an opt-in flag or mode that just brings in all page styles would work as expected in all cases. Some shadow styles could unexpectedly lose. Or get pulled back into a specificity race that could feel like shadow trees just gave up.

Prioritization is required.

Or maybe just unavoidable, since unlayered styles are of necessity assigned a layer priority. And a limited form of priority for shadow trees already exists in the context step, so any brought-in styles would pass through that step too.

i understand all of these as possible solution requirements. in order to frame them, i would still love to see each of these connected to a direct user need in terms of the typical user story framing.

how do these items get put into a sentence like:

“As a {person} i would like {feature/requirement} so that I can {do a specific thing}.

i think this exercise and framing will help tie stuff like “prioritization is required” to a direct reason WHY prioritization is required in terms of a person and their ability/non-ability to build things.

zaygraveyard commented 3 months ago

Two non-mutually exclusive use cases concerning styling shadow DOM elements from outside the component that I wish can be supported (but not sure if they can be part of this initiative/proposal):

EDIT: On second thought, they might be mutually exclusive, not sure 🤔

DarkWiiPlayer commented 3 months ago

Here's an attempt at counting how many of these user stories imply a need for:

User pull push layers combinators
@mayank99 2 0 1 0?
@zaygraveyard 0 1 0 0
@darkwiiplayer 2 0 2 1
@knowler 1 0 1 0
@robglidden 1 2 1 0
Total 6 3 5 1

I will attempt to update this list as more user-stories come in (as time allows). Feel free to suggest additional considerations to track.

DarkWiiPlayer commented 3 months ago

When developing web applications for company-internal use, I want to re-use web components that represent common logic across various projects regardless of what tech stack they individually use. When frameworks are used that require extra classes, I want to extend the components to use templates and have the framework classes available automatically inside the component.

robglidden commented 3 months ago

@michaelwarren1106, @rniwa:

It seems to be getting missed that modern browsers support "Declarative Shadow DOM".

The "user" in the above use cases and requirements is just the user of a shadow tree, particularly a declarative shadow tree.

To elaborate:

Declarative shadow DOM already gives web component users a way to present a shadow tree (with user-written CSS styles in it) to the web component. And a way for the web component to accept, reject, or use those styles as it sees fit.

So user stories that boil down to something like "as a web component user I want the web component to consider using some styles I present to it in a shadow tree" is not a missing platform feature, it is a choice for web component authors to make.

What is missing is a way to bring page styles into shadow trees.

Without this common context, there seems to be a conflation loop.

Classifying as "push" vs "pull" vs "other" seem to suffer similarly.

michaelwarren1106 commented 3 months ago

user stories that boil down to “as a user i need X so that Y” is precisely for the purpose of making sure we don’t conflate things and are crystal clear about what to ask implementers for and why.

if the user stories you are thinking of are more specific than “as a web component user” then that’s great! let’s capture those under a different persona. like “as a developer using shadow trees with declarative shadow dom, i need X so that Y”.

what i think implementers are asking for, and the purpose of my creating this issue is about finding all the Xs and the Ys.

we all have different opinions on the “what do people want” it’s the “so that Y”s that really matter. specifying what devs are unable to do today, or what things are difficult/cumbersome today is the entire reason to change things. calling some feature being “a missing platform feature” isn’t as powerful as describing specifically what that new feature will accomplish that matters.

in the other thread, and now starting in this one, there’s been a lot of “i think it should be this way” and not enough “if it is {this way} then {persona} can do {thing} way easier/simpler/faster/better etc etc“.

we need to get at the specifics of what folks are trying to do. enumerate those first. THEN work on solutions that solve those cases. as of yet we’ve been working backwards from opinions about things we think are needed and not working forward from actual outlined spelled out problems.

DarkWiiPlayer commented 3 months ago

@robglidden

It seems to be getting missed that modern browsers support "Declarative Shadow DOM".

Declarative Shadow DOM is an optimisation to avoid FOUC by pre-rendering the contents of a shadow DOM on the server or during deployment. It's not an entirely new way of doing shadow DOM, just an additional API to attach and initialise it. The problems with styling remain the exact same ones: Outside style-sheets don't affect the insides of the shadow DOM.

  • Shadow trees are not "Custom Elements"

I think you're missing the forest for the trees here, no pun intended. Shadow DOM is primarily useful in combination with custom elements and <template>s to build web components. They can be attached to other elements, yes, but that is a very rare way of using them, so it makes sense for most of these user stories to focus on this main use-case.

If you have any user stories that showcase the use of shadow-dom with normal HTML elements, I'd be curious to see those to get another perspective on the spec, but if you don't actually post them here, then we can't read your mind.

So user stories that boil down to something like "as a web component user I want the web component to consider using some styles I present to it in a shadow tree" is not a missing platform feature, it is a choice for web component authors to make.

It is not per se a missing feature, as it can be done imperatively using Javascript, but it is a common enough case for a specific platform feature to be added to make it more ergonomic and resilient. Synchronising stylesheets between light- and shadow-dom is far from trivial with the APIs we currently have.

Classifying as "push" vs "pull" vs "other" seem to suffer similarly

I disagree. Classifying as "push" vs "pull" is very important because it is the distinction between whether the component author or the component user is the one who initiates the style adoption. The open-stylable proposal specifically addresses the former case, where a component author wants to opt in to some or all styles defined by the component user. It preserves encapsulation except where the author specifically chooses to expose APIs to let the user influence the process.

Separating user stories into which of the two they need is important to know whether a push-based mechanism is worth exploring further, either as a separate feature, or as a part of open-stylable, or a purely pull-based mechanism can cover most of the users' needs.

Again, if you think there's another, more important axis to consider, it'd be much easier if you could explain it with some actual user stories or at least specific use cases. I think this issue was created precisely because just listing requirements seems a bit arbitrary to us strangers on the internet, and user stories are a convenient way of bundling a requirement with the context to show why that requirement is useful.

robglidden commented 3 months ago

@michaelwarren1106:

No objection from me, user stories are valuable.

I am saying something different.

The primary use case #909 was opened for in 2020 is component library maintainers who want to move to web components while supporting stylesheets that they don't control. And there are important related use cases.

But now, years later, declarative shadow DOM directly addresses many of these related use cases.

In particular, declarative shadow DOM already provides a way for web component users to present user written styles to web components. In a way that answers the often-expressed need on behalf of web component authors to have opt-in say before accepting those styles into web components.

So I am saying it doesn't make sense to collect user stories for something that was already considered and implemented in web browsers. To me, the problem to solve is bringing page styles into shadow trees, not some other already solved problem.

So no, I am not saying or implying at all that I am thinking of (or being cagey about) user stories that are more specific than "as a web component user". That's backwards.

robglidden commented 3 months ago

@DarkWiiPlayer:

Declarative Shadow DOM is most powerful when used with "Custom Elements".

Declarative shadow trees were designed exactly to support the case of web component users presenting shadow trees to web component authors to consider using in a more declarative, ergonomic, resilient, and component-author-acceptable way than imperative Javascript.

To me that's the other, more important axis to consider.

rniwa commented 3 months ago

That's not really use cases / user stories. Use cases are specific scenarios in which specific piece of software may be used in a specific way, not some general statement about what kind of problem ought to be solved.

robglidden commented 3 months ago

"as a web component user I want the web component to consider using some styles I present to it in a shadow tree"

That is the user story that is already asked and answered by declarative shadow DOM.

justinfagnani commented 3 months ago

I don't understand the relationship of declarative shadow DOM to the discussion here.

As an implementation detail, not a user story, any new mode or option to attachShadow() would be available as an attribute on the DSD template. Other than that, shadow roots created imperatively and declaratively are basically the same. Open-stylable would obviously be available on both.

Users of a component being able to provide their own shadow root to a custom element is, honestly, a pretty niche use of shadow DOM. I know of no components written this way and I wouldn't want to have to resort to this - which would interfere with the component having it's own shadow root - as a way of theming components. We should be able to do better.

But also... theming is different from open-stylable. Open stylable is a proposal to solve a problem affecting components migrating from light DOM to shadow DOM. There are still lots of other problems around theming that are better solved, IMO, with specific theming APIs that don't require completely opening up a shadow root to styles, and work with ::part().

edit:

Declarative shadow trees were designed exactly to support the case of web component users presenting shadow trees to web component authors to consider using in a more declarative, ergonomic, resilient, and component-author-acceptable way than imperative Javascript.

This is historically incorrect. Declarative shadow DOM was designed to support server-side rendering of shadow roots. Their main use case has been as a serialization of shadow roots that would have been created with attachShadow() - ie, as an internal component feature. In fact, some of the discussion was around how to mitigate the hazard of users placing shadow roots on components they don't own and therefore breaking the component. They were not designed for ergonomics or to be in any way more "component-author-acceptable" than attachShadow().

michaelwarren1106 commented 3 months ago

i feel like i should just close this issue and try to compile user stories elsewhere. this issue is rapidly turning into another debate about solutions and proposals instead of merely listing problems needing solving.

we don’t need another thread for debating proposals, terms and concepts. that will just derail any progress

robglidden commented 3 months ago

@justinfagnani:

Declarative Shadow DOM can be used on its own as a way to encapsulate styles or customize child placement, but it's most powerful when used with Custom Elements.

is a direct quote from a Google web site.

Please, I would not want to be misinterpreted if I said "Google, meet Google". So I won't say it.

rniwa commented 3 months ago

Please don't use this issue to discuss things. That's the point of https://github.com/WICG/webcomponents/issues/909. This issue should focus on collecting specific use cases.

knowler commented 3 months ago

User story: I’m building a web app. I’ve already written the styles for various user interface elements (e.g. buttons, form controls). Now I have a larger composition that I need to repeat throughout the app which includes a number of these elements (e.g. a modal dialog that includes a few buttons) and I would like to use the shadow DOM for this. Slots are the wrong tool for the job since the component doesn’t need the composition they provide. Parts are equally awkward since they require me to rewrite my CSS. I would love to write the styles for these elements once, then allow the web components in my app use them (ideally without requiring my entire stylesheet also be applied to the shadow root).

Why slots are awkward for this use case?

DSD used purely for example and some details might be left out: ```html ``` Problem: I’m not interested in making this abstraction super flexible. Needing to use slots here is creating extra work when I want to use the component: I want the component itself to know which buttons to use, what their text content should be, and any sort of other attributes they need. Further, requiring the buttons to be provided as slotted content makes this more prone to failure.

Why parts are awkward for this use case?

DSD used purely for example and some details might be left out: ```html ``` To style these I need to use `::part(confirm-button)` and `::part(cancel-button)`. ```css .button, ::part(confirm-button), ::part(cancel-button) { /* button styles */ } .button--danger, ::part(confirm-button) { /* button danger styles */ } .button--secondary, ::part(cancel-button) { /* button secondary styles */ } ``` You might have noticed that these part names aren’t great for mapping to my button classes. They are what I might expect from a custom element though since they are more semantic. It could be better if I wrote my custom element but instead use more presentational part names: ```html ``` Now when I write my CSS it’s a bit better: ```css .button, ::part(button) { /* button styles */ } .button--danger, ::part(button--danger) { /* button danger styles */ } .button--secondary, ::part(button--secondary) { /* button secondary styles */ } ``` In this situation the problem might well be solved for this use case, however, it requires a strict one-to-one in regard to part name and class name. If I use a third party component, then I might not get the presentational information that I need from the part names and end up needing to do something like the first parts example. Further, now since my button selector is not just `.button` in my system, any element that contains buttons needs to select both `.button` and `::part(button)`.

Why not wrap your styled elements in custom elements so they can be used in shadow roots?

- Form associated elements won’t associate with any forms they are a part of—there would need to be extra logic written to make that work (i.e. making the wrapper element a form associated element). - Third party custom elements don’t know about my styled custom element, so this requires me to have the styles available to apply to parts that they might expose. - I don’t want to modularize my entire CSS component library just to use the Shadow DOM.

Why not all the styles (the entire stylesheet or all the stylesheets)?

Any styles that are allowed into a shadow root will potentially match something in the shadow root, so I personally would like to restrict that to a minimum, since otherwise the benefits of the _isolation_ aspect of style encapsulation completely go away. For example, if I let all the styles in, then I both need to be more careful with how I write my document-level styles and more guarded with how I write my shadow root’s styles. By only allowing in what the component needs (it doesn’t have to necessarily use all of the allowed styles), then I am still able to enjoy all the benefits of style encapsulation and have some external styles to use for my component abstraction. Note that I am still very much interested in using the existing shadow DOM styling features (i.e. parts, slots, etc.) for styling _concrete_ uses of my components. If any of the concrete uses of my components need more access to its shadow root for styling (e.g. more than the parts API can provide), I would prefer to keep that as an exception and apply those styles specifically to the shadow root that they apply to. I find that this becomes a lot more maintainable since generally the concrete uses of the component are styled with a more robust and declarative styling API (e.g. `delete-dialog::part(confirm-button)`), while any exceptions are very clearly highlighted as being so.

rniwa commented 3 months ago

@knowler : That's some good concrete use case, thank you! Could you elaborate why applying the entire stylesheet is problematic in your use case?

bkardell commented 3 months ago

@rniwa just for clarification when you say "the entire stylesheet" do you mean "all of the page level stylesheets"? (or is it tree scoped, or something else?) It's the word "the" I'm asking about I guess. It seems to indicate that we've somehow identified a specific stylesheet, and I'm not sure if you meant that or not?

robglidden commented 3 months ago

Here are user stories and corresponding Web Platform Tests for the collection of user stories #1052 for "open-stylable" Shadow Roots #909.

You can find the actual web platform tests in the shadow layers proposal repository.

01 Page resets As a web page author I just want my page resets to work in my shadow tree so that buttons in the shadow tree match buttons outside the shadow tree. ```html ```
02 Nested shadow trees As a web page author or shadow tree designer, I want to use declarative shadow DOM to design a `` for my page so that buttons in `nav-bar` get their style from ``, and the Home button gets its style from the page styles. No Javascript, no Flash of Unstyled Content, no attachShadow() or CustomElements.define(). ```html ```
03 Web component from another entity As a web page author I want to pass some page styles into a web component from another entity whose internal styles I do not control, so that the web component will use those styles. ```html ```
04 Web component rejects user styles As a web component author I want to reject any page styles that the web component user offers me to use, so that the styles in the web component are never affected by outer styles. ```html ```
05 Page styles at low priority As a shadow tree designer I want the user of the shadow tree to be able to bring in their page styles at a low priority, so that default styles in the shadow tree will win over brought-in page styles. ```html ```
06 Page styles at high priority As a shadow tree designer I want the user of the shadow tree to be able to bring in their page styles at a high priority, so that brought-in page styles will win over default styles in the shadow tree. ```html ```
07 All page styles at low priority As a shadow tree designer I want the user of the shadow tree to be able to bring in all their page styles at a low priority, so that default styles in the shadow tree will win over brought-in page styles. ```html ```
08 All page styles at high priority As a shadow tree designer I want the user of the shadow tree to be able to bring in all their page styles at a high priority, so that brought-in page styles will win over default styles in the shadow tree. ```html ```
09 Web component all page styles low priority As a web component author I want to bring in all page styles at a low priority without the web component user doing anything, so that default web component styles will win over brought-in page styles. ```html ```
10 Web component all page styles high priority As a web component author I want to bring in all page styles at a high priority without the web component user doing anything, so that brought-in page styles will win over default web component styles. ```html ```
rniwa commented 3 months ago

@rniwa just for clarification when you say "the entire stylesheet" do you mean "all of the page level stylesheets"? (or is it tree scoped, or something else?) It's the word "the" I'm asking about I guess. It seems to indicate that we've somehow identified a specific stylesheet, and I'm not sure if you meant that or not?

I'm talking about the stylesheet referred to in "ideally without requiring my entire stylesheet also be applied to the shadow root". Not sure if knowler meant all of page's stylesheets, or a specific stylesheet imported by link / @import. I'd like to understand what use cases lead to the need to filter, or selectively apply, style rules because that seems like a key question here as I mentioned in https://github.com/WICG/webcomponents/issues/909 as well.

knowler commented 3 months ago

Could you elaborate why applying the entire stylesheet is problematic in your use case?

@rniwa I updated my comment above (under “Why not all the styles (the entire stylesheet or all the stylesheets)?”) to answer your question.

Not sure if knowler meant all of page's stylesheets, or a specific stylesheet imported by link / @import. I'd like to understand what use cases lead to the need to filter, or selectively apply, style rules because that seems like a key question here as I mentioned in https://github.com/WICG/webcomponents/issues/909 as well.

For the use case above, I meant that I don’t want all of the document’s stylesheets. That use case is more flexible in regards to how I structure/split up my stylesheets, so if I needed to split out the styles I want to be included in the shadow roots into a separate stylesheet, then I wouldn’t have any issue doing that. I guess one potential complication is that I am likely using layers in the document (especially to facilitate any code splitting), but in the shadow root I might have a different layering structure or no layering structure, so that would need to be considered if a singular mechanism for applying to styles to both the document and shadow root is used.

DarkWiiPlayer commented 3 months ago

Inspired by the recent comment in the feature issue:

As a website author, I want to structure my CSS however works best for my project and make as little changes as possible to achieve compatibility with the web components I want to or may in the future want to use. When changes have to be made, they should be generic and semantic and not specific to the components.

As an added example: If I want a component <contact-form> to inherit resets.css and framework.css from the light-dom, I should not be expected to somehow mark those two files as used by contact form, but at best instruct the <contact-form> to use two files, and at worst mark those two files as "resets" and "basic styles / framework" in a way that works or can work for any other similar component from different authors.

In other words, every mechanism for selecting to use styles from resets.css but not from footer.css should work regardless of whether those two files are linked using a <link> tag, an @import tag or are inlined in a <style> tag.

DarkWiiPlayer commented 3 months ago

As a component author, I want to build components that default to inheriting all the outside styles, but allow users to narrow down what styles get inherited. I want to define my own API for this to have proper control over how much flexibility I want to give to my users.

DarkWiiPlayer commented 3 months ago

As a component author, I want to inherit the outside styles not into the entire shadow-dom, but into a scope to make sure outside styles cannot mess with certain parts of my component like a top level grid wrapper. For example when populating the shadow-dom with my own HTML, then inserting generated HTML into that structure.

DarkWiiPlayer commented 3 months ago

As a website author / component user, I want components to follow the surrounding theme and not end up with, e.g., a dark-mode contact form in a light-mode website or vice versa.

I bring this one up because it might depend on selectors like .dark button { color: white } detecting a button inside a shadow DOM attached to a descendant from a class="dark" element. I suspect getting combinators to work like this might cause some massive headache to the browser people, so I want to make extra sure these problems get discussed as early as possible.

knowler commented 3 months ago

As a website author / component user, I want components to follow the surrounding theme and not end up with, e.g., a dark-mode contact form in a light-mode website or vice versa.

I bring this one up because it might depend on selectors like .dark button { color: white } detecting a button inside a shadow DOM attached to a descendant from a class="dark" element. I suspect getting combinators to work like this might cause some massive headache to the browser people, so I want to make extra sure these problems get discussed as early as possible.

@DarkWiiPlayer Some of those cases are potentially solvable with container style queries using custom properties (e.g. @container style(--theme: dark)). Not quite the same as using a class name, since they can be “intercepted” as they inherit down a tree (but in many ways that would be better for theming).

In any case, this is good to highlight, so thanks for bringing this up.

robglidden commented 3 months ago

Here are updated user stories and corresponding Web Platform Tests for the collection of user stories #1052 for "open-stylable" Shadow Roots #909.

01 Page resets As a web page author I just want my page resets to work in my shadow tree so that buttons in the shadow tree match buttons outside the shadow tree. ```html ```
02 Nested shadow trees As a web page author or shadow tree designer, I want to use declarative shadow DOM to design a `` for my page so that buttons in `nav-bar` get their style from ``, and the Home button gets its style from the page styles. No Javascript, no Flash of Unstyled Content, no attachShadow() or CustomElements.define(). ```html ```
03 Web component from another entity As a web page author I want to pass some page styles into a web component from another entity whose internal styles I do not control, so that the web component will use those styles. ```html ```
04 Web component rejects user styles As a web component author I want to reject any page styles that the web component user offers me to use, so that the styles in the web component are never affected by outer styles. ```html ```
05 Page styles at low priority As a shadow tree designer I want the user of the shadow tree to be able to bring in their page styles at a low priority, so that default styles in the shadow tree will win over brought-in page styles. ```html ```
06 Page styles at high priority As a shadow tree designer I want the user of the shadow tree to be able to bring in their page styles at a high priority, so that brought-in page styles will win over default styles in the shadow tree. ```html ```
07 All page styles at low priority As a shadow tree designer I want the user of the shadow tree to be able to bring in all their page styles at a low priority, so that default styles in the shadow tree will win over brought-in page styles. ```html ```
08 All page styles at high priority As a shadow tree designer I want the user of the shadow tree to be able to bring in all their page styles at a high priority, so that brought-in page styles will win over default styles in the shadow tree. ```html ```
09 Web component all page styles low priority As a web component author I want to bring in all page styles at a low priority without the web component user doing anything, so that default web component styles will win over brought-in page styles. ```html ```
10 Web component all page styles high priority As a web component author I want to bring in all page styles at a high priority without the web component user doing anything, so that brought-in page styles will win over default web component styles. ```html ```
11 Designer or author provided template As a shadow tree designer or web component author, I want to provide users a default template of CSS and/or HTML so that users can knowledgeably bring in page styles. ```html ```
12 Revert to parent shadow tree As a shadow tree user, I want to bring in styles from a parent shadow tree so that shadow trees that are children of shadow trees will have styles consistent with the parent shadow trees. (currently unimplemented in shadow layers proposal) CSS: ```css @layer buttons, revert.parentshadowbuttons; ``` Example: ```html ```
13 Polyfillable As a web author, shadow tree designer or user, or web component author or user I want any solution for bringing in page styles to shadow trees to be polyfillable, so that I can evaluate, test, adopt and deploy it in a timely matter. This seems particularly important for an HTML-parser level feature. See the user-story-tests folder in the shadow layers proposal [repository](https://github.com/htmlcomponents/shadow-layers).
14 Inherit resets layer as higher priority renamed layer As a web page author I want to bring in my resets layer as a renamed layer so that it can have higher priority than the shadow tree's own reset layer. ```html ```
15 Inherit resets layer as lower priority renamed layer As a web page author I want to bring in my resets layer as a renamed layer so that it can have lower priority than the shadow tree's own reset layer. CSS: ```css @layer inherit.resets.as.shadowresets, shadowresets, resets; ``` Example: ```html ```
16 Interweave priorities of outer and inner context layers As a web page author I want to interweave priorities of outer and inner context layers so some have lower priority of a shadow tree layer and some have higher priority of a shadow tree layer. CSS: ```css @layer inherit.A.as.outerA, inherit.B.as.outerB, outerA, A, B, outerB; ``` Example: ```html ```
17 Inherit @scope page style As a declarative shadow tree or web component user, I want to bring into a shadow tree a page style that includes an @scope rule in a layer, so that I can give the outer context @scope rule priority over an inner content @scope rule. ```html ```
18 Inherit named @sheet as layer As a declarative shadow tree or web component user, I want to bring into a shadow tree a page style that includes an @sheet in a layer, so that I can give the outer context @sheet priority over an inner content styles. [At-rule support detection in @supports](https://www.bram.us/2022/01/20/detect-at-rule-support-with-the-at-rule-function/) is not available, so @sheet would not be polyfillable [Multiple stylesheets per file #5629](https://github.com/w3c/csswg-drafts/issues/5629), so the POC does not implement @sheet. However, @layer is widely deployed so polyfillability is not needed for it, and @layer also provides the essential priority mechanism. Nonetheless, an @sheet supporting syntax would be possible: ```css //Inherit named sheet as layer @layer inherit.sheet.mysheet.as.mysheet, mysheet; ```
19 Inherit unlayered page styles as lower priority layer As a user or author of a declarative shadow tree or web component I want to bring in unlayered page styles into a shadow tree so that the outer context unlayered page styles will have lower priority than the shadow tree styles. In CSS: ```css @layer inherit.unlayered.as.unlayered, unlayered, shadowstyles; ``` Example: ```html ```
20 Inherit unlayered page styles as higher priority layer As a user or author of a declarative shadow tree or web component I want to bring in unlayered page styles into a shadow tree so that the outer context unlayered page styles will have higher priority than the shadow tree styles. In CSS: ```css @layer inherit.unlayered.as.unlayered, unlayered, shadowstyles; ``` Example: ```html ```
21 Interweave priorities of outer layered and unlayered styles As a user or author of a declarative shadow tree or web component I want to bring in both layered unlayered page styles into a shadow tree, so that the outer context layered and unlayered page styles can interweave with the shadow tree styles. In CSS: ```css @layer inherit.layered.as.layered, inherit.unlayered.as.unlayered, layered, shadowstyles, unlayered; ``` Example: ```html ```
22 Inherit all outer page styles As a user or author of a declarative shadow tree or web component I want to bring in both layered unlayered page styles into a shadow tree, so that the outer context unlayered styles have priority over outer context layered styles. In CSS: ```css @layer inherit.unlayered.as.unlayered, inherit.unlayered.as.unlayered, layered, unlayered; ``` Example: ```html ```
23 Pass through from design system As a user of a design system and a web component or declarative shadow tree, neither of which I control the styles, I want to pass CSS framework styles into the web component or declarative shadow tree, so that the web component or declarative shadow tree can be styled consistent with the CSS framework. Example: ```html ```
24 Pass through from layered CSS framework As a user of a layer-aware [low-priority CSS framework](https://github.com/w3c/csswg-drafts/issues/6284#issuecomment-1006946621) and a web component or declarative shadow tree, neither of which I control the styles, I want to pass CSS framework styles into the web component or declarative shadow tree, so that the web component or declarative shadow tree can be styled consistent with the CSS framework. Example: ```html ```
robglidden commented 3 months ago

Additional user stories and corresponding web platform tests for the collection of user stories #1052 for "open-stylable" Shadow Roots #909.

25 Inherit @imported CSS file As a shadow tree or web component user, I want to inherit into a shadow tree a CSS file that I have already @imported into the page outside the shadow tree, so that I don't have to @import the same CSS file twice (once into the page, and again into the shadow tree). In other words, I don't want to have to do this: resets.css file: ```css button { border: thick dashed red; } ``` Double @import I don't want to do: ```html @import assets/resets.css; ``` See also [Allow authors to apply new css features (like cascade layers) while linking stylesheets #7540](https://github.com/whatwg/html/issues/7540) and [Provide an attribute for assigning a `` to a cascade layer #5853](https://github.com/w3c/csswg-drafts/issues/5853). Example: ```html @import assets/resets.css layer(resets); ```
26 Page styles only affecting shadow tree

As a shadow tree or web component user, I want to provide some page styles outside a shadow tree that won't affect the page at all but can be inherited into the shadow tree, so that I can write page styles that only affect shadow trees.

- Note that [when evaluated in the context of a shadow tree](https://drafts.csswg.org/css-scoping/#host-selector), `:host( )` matches the shadow tree’s shadow host if the shadow host, in its normal context, matches the selector argument. In any other context, it matches nothing. - `:host` behaves similarly in any other context. ```html ```
knowler commented 3 months ago

Hi all, let’s make this a GitHub Discussion: https://github.com/w3c/webcomponents-cg/discussions/92

I think that format will help us keep individual user stories surfaced and will allow us to as further questions to clarify each use case.

Feel free to move your use cases over there. I’ll circle around in the next week to collect any that have been missed.

robglidden commented 3 months ago

Here are additional user stories and corresponding web platform tests for the collection of user stories #1052 for "open-stylable" Shadow Roots #909.

27 Markdown component with automatic page styles As a web component author, I want to write a web component that transforms markdown into HTML and brings in page styles, so that transformed markdown is styled from page styles without the web component user having to do anything. A [prototypical](https://github.com/WICG/webcomponents/issues/909#issuecomment-1936910846) `` web component with page styles. ```html

H2 outside shadow tree

```
28 Markdown component with author-defined page layer As a web component author, I want to write a web component that transforms markdown into HTML and brings in a page layer with a name that I designate, so that the transformed markdown is styled from the named page layer I designate. ```html

H2 outside shadow tree

```
29 Markdown component with author-defined lower priority shadow layer As a web component author, I want to write a web component that transforms markdown into HTML and brings in page styles, so that the transformed markdown is styled from page styles if they exist and if not the transformed markdown is styled by default web component provided styles, without the web component user having to do anything. ```html

H2 outside shadow tree

```
30 Markdown component with author-defined higher priority shadow layer As a web component author, I want to write a web component that transforms markdown into HTML and brings in page styles, so that the transformed markdown is styled from page styles, but if web component default styles exist they have higher priority, without the web component user having to do anything. ```html

H2 outside shadow tree

```
31 Markdown component with user-selectable page styles As a web component author, I want to write a web component that transforms markdown into HTML, and has default markdown styles and user-selectable page styles, so that the transformed markdown is styled by either the defaults or by the styled user-selectable page styles, as the user sees fit. ```html

H2 outside shadow tree

```
32 Markdown component with page @scope As a web component author, I want to write a web component that transforms markdown into HTML, and has default markdown styles and user-selectable page styles, so that the transformed markdown can be styled by a user-provided @scope page style. ```html

H2 outside shadow tree

```
robglidden commented 3 months ago

Here are additional user stories and corresponding web platform tests for the collection of user stories #1052 for "open-stylable" Shadow Roots #909.

33 Component library with CSS file and page styles As a shadow-tree-based component library author or maintainer I want to provide a single, once-imported CSS file for all the components in the library and also bring all page styles into some of the components, so that library and page styles only apply to some or all components as appropriate. Exemplar imperative components: - **``**: An imperative (Javascript) component that transforms and displays markdown contained in a ` ```
34 Component library with declarative and imperative components and page styles As a shadow-tree-based component library author or maintainer starting from the component library in "33 Component library with CSS file and page styles", I want to add declarative-only components (components built with declarative shadow DOM and no Javascript), so that the library provides both declarative and imperative components. Exemplar declarative component: - **``**: A declarative component (no Javascript declarative shadow tree) that styles semantic HTML elements section, header, and footer. (A platform-encapusulated version of a [very commonly](https://wordpress.com/support/wordpress-editor/blocks/group-block/) implemented [web design pattern](https://university.webflow.com/lesson/container?topics=elements)). ```html
Section outside shadow tree

H2 outside shadow tree

section-container
```
35 Component library with multi-component user-settable lower and higher priority page styles As a shadow-tree-based component library author or maintainer starting from the component library in "34 Component library with declarative and imperative components and page styles", I want to add multi-component user-settable lower and higher priority page styles, so that users can provide page styles that have either lower or higher priority than component default styles. ```html
Section outside shadow tree

H2 outside shadow tree

```
36 Component library with individual component user-settable lower and higher priority page styles As a shadow-tree-based component library author or maintainer starting from the component library in "35 Component library with multi-component user-settable lower and higher priority page styles", I want to add to individual components user-settable lower and higher priority page styles, so that users can bring in and priortize any page style layers they want. ```html
Section outside shadow tree

H2 outside shadow tree

```
michaelwarren1106 commented 2 months ago

All,

I've spent some time going through the use cases and trying to organize and categorize them in a way that might be useful in discussions with browser implementors. I tried to analyze and combine similar use cases into representative use cases and categories. I've also disregarded any use cases that I thought were pointing too directly at a solution like "I want to use css layers to do ...." or "I want to use @sheet to push styles into a component". Personally, I don't think use cases should pre-dispose solutions, only describe problems that are currently difficult to implement in today's world. The solutions discussions come after the use cases, imo.

Here's what I have come up with.

Global CSS Approach/Framework / Reset

Building apps completely from web components

Web components in “hostile” environments

Inherit styles from a parent root instead of the document

Headless Components

DSD - Out of order streaming

DSD - reduce repetitive styles

Open Questions / Use Cases / Features of a solution?

If I've missed (or disregarded) your use case, and you feel it important to include and appreciably different from the ones captured above, I'm happy to amend the list. If you can phrase your use case in the "As a , I want __ so that " format without pre-supposing a solution/approach, I'll add.

thepassle commented 2 months ago

Thanks for summarizing @michaelwarren1106 🙂 Slight nit on the DSD out of order streaming summary:

- requires a shadowRoot on the element.
+ requires a shadowRoot on the body element.
michaelwarren1106 commented 2 months ago

Thanks for summarizing @michaelwarren1106 🙂 Slight nit on the DSD out of order streaming summary:

- requires a shadowRoot on the element.
+ requires a shadowRoot on the body element.

haha i had it as html and github ignored it hehe. put backticks around it