Replies: 9 comments 5 replies
-
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: <delete-dialog>
<template shadowrootmode=open>
<dialog>
<form method=post>
<slot name=confirm-button></slot>
<slot name=cancel-button></slot>
</form>
</dialog>
</template>
<button class="button button--danger" slot=confirm-button>Yes, delete it.</button>
<button class="button button--secondary" slot=cancel-button formmethod=dialog>Cancel</button>
</delete-dialog> 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: <delete-dialog>
<template shadowrootmode=open>
<dialog>
<form method=post>
<button part=confirm-button>Yes, delete it.</button>
<button part=cancel-button formmethod=dialog>Cancel</button>
</form>
</dialog>
</template>
</delete-dialog> To style these I need to use .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: <delete-dialog>
<template shadowrootmode=open>
<dialog>
<form method=post>
<button part="confirm-button button button--danger">Yes, delete it.</button>
<button part="cancel-button button button--secondary" formmethod=dialog>Cancel</button>
</form>
</dialog>
</template>
</delete-dialog> Now when I write my CSS it’s a bit better: .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 Why not wrap your styled elements in custom elements so they can be used in shadow roots?
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. |
Beta Was this translation helpful? Give feedback.
-
User story: 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. As an example, I definitely want my consumer's global CSS resets to be automatically applied to my components. There is no good reason I should have to include I am ok with the tradeoff that any DOM changes I make to future versions of my component can break my consumer's styles. (Adapted from my earlier comment) |
Beta Was this translation helpful? Give feedback.
-
User story: 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. I build these components with my own mechanism of scoped styling (e.g. namespacing, build tools), so I may not even need shadow-root style encapsulation. Often, I even have my own component framework that runs outside of the browser. I want to be able to mix-and-match light DOM and shadow DOM in these framework components and reuse styles across them. (See example) (Adapted from my earlier comment) |
Beta Was this translation helpful? Give feedback.
-
As a website author, I consume components from various sources: Some that I made, some that other teams at my company have made, some provided from our CMS vendor, and some that we've found online ourselves. I would like to be able share or collaborate better with some of them - including providing some already written, simple base styles or resets to help them match my look and feel. Since my page styles are untested, I would like the ability to choose which elements I provide those styles to, as well as which styles. Also, as an engineer I would like to optimize this/it feels bad to me to suggest that |
Beta Was this translation helpful? Give feedback.
-
As a component (or library) author, I have some nested components. I would like to share some common resets and styles at the native element level (buttons, inputs, etc) across all of my sub-components (some of which perhaps are not mine, but are also 'open' to styling, while more generally working with abstractions - shadows/parts. |
Beta Was this translation helpful? Give feedback.
-
User story: As a component library author, I want to distribute a single shared This
For some components in my library, I also want to prevent arbitrary unscoped styles from leaking into shadow-roots by default. I'm happy to provide my consumers the added flexibility if they need it, but I want to make them opt into it. This is for their own sake, especially if their codebase does not practice good CSS hygiene. Why not
|
Beta Was this translation helpful? Give feedback.
-
User story: As a part of our WordPress plugin, we have a public facing widget that can be embedded into any page or post. We’re using the shadow DOM since to be frank WordPress is quite hostile: it’s impossible to predict the concoction of different themes and plugins or even custom CSS from the site owner. Our widget is fairly complex — it’s almost an entire app. WordPress being Wordpress, we have users who want the level of customization that they’re used to. Shadow parts are our only option, however, it’s a lot of work to not only add generic parts (e.g. |
Beta Was this translation helpful? Give feedback.
-
User story: using declarative shadow DOM, you can achieve out of order streaming of content, without the need for JS to replace content when it's ready. Here's a blogpost on that: https://lamplightdev.com/blog/2024/01/10/streaming-html-out-of-order-without-javascript/ The streamed HTML for that would look something like this: <html>
<body>
<template shadowrootmode="open">
<h1>Hello world</h1>
<slot name="id-1"></slot>
<footer>Copyright</footer>
</template>
<div slot="id-1">Content loaded!</div>
</body>
</html> The downside to this is that it uses a shadowroot on the body, because you need slots for this which is a shadow dom feature, which then bars you from global styling. |
Beta Was this translation helpful? Give feedback.
-
User story: As a "UserCSS" user I want to be able to affect all elements in displayed pages including shadow DOM with my recipes. Currently only "true native user-origin level stylesheets" (userContent.css in Firefox) can help with that (*), but since it is cumbersome to use, nearly nobody uses them, so convenience of author-level injected "UserCSS" managed by "userCSS/style managers" (like Stylus) won. Yet increasing adoption of web components increases "unstylable" areas so effecively threatens the main goal of said managers. (This is a matter for closed shadow DOM, perhaps.) (*) Failing that would mean non-compliance with UAAG and CSS (since 2.1) standards, iiuc. |
Beta Was this translation helpful? Give feedback.
-
We want to collect concrete user stories for the open shadow root styling issue (WICG/webcomponents#909). There was a recent issue opened for this purpose (WICG/webcomponents#1052), however, the issue format makes it harder to both keep the use cases surfaced and to facilitate further discussion specific to individual stories.
Some guidelines to make the most of this:
+1
or 👍🏻, use the up-vote feature for the user stories that reflect your own experience. If the original issue can teach us anything, it’s that more noise isn’t going to help us get anywhere (it just makes everything harder to follow).<details>
element if that helps keep the story focused while providing longer code blocks.Beta Was this translation helpful? Give feedback.
All reactions