-
Notifications
You must be signed in to change notification settings - Fork 744
Description
First filed in whatwg/dom#1348, but that was the wrong repo
What problem are you trying to solve?
I want to be able to use shadow DOM for display encapsulation, but while still being able to use global styles and participate in its inheritance.
What solutions exist today?
Currently, I could use shadowRoot.adoptedStyleSheets = [...globalSheets]
. But doing this comes with a cost: these style sheets take precedence over local <style>
elements (this can be easily worked around by removing the element and adopting its parsed style). Furthermore, it doesn't work with declarative shadow DOM at all.
Alternatively, I could inject all the global styles with duplicate <link rel="stylesheet">
s. This comes with serious performance concerns: imagine a hundred posts on a TweetDeck-style UI for a microblogging site, each with <format-time>
to format the time, <user-link>
to format the username, and <format-text>
to format the text. If you have 5 stylesheet tags on the site (say, normalize.css, your site's styles, Bootstrap, and a couple Bootstrap plugins) and want to use them all in that custom element's shadow DOM, that's 500 <link rel="stylesheet">
elements in that one page. The browser can cache style parsing per-URL to avoid the memory blow-up, but the browser can't avoid having to compute the entire stylesheet for every page, leading to high style compute times.
And in both cases, the cascade can't go through the shadow DOM.
How would you solve it?
Add a styleOrder
ordered token list option for shadow root initializers:
outer
- Set to apply parent styles.- If a shadow host is in a
div
in a parent and the corresponding shadow root's children has aspan
, the CSS selectordiv span
would match the inner child. - If a shadow host is a
foo-bar
in a parent and the corresponding shadow root's children has a top-levelspan
, the CSS selectorfoo-bar > span
would match the inner child.
- If a shadow host is in a
adopted
- Set to apply adopted stylesheets. If not included,shadowRoot.adoptedStyleSheets
has no effect.inner
- Set to apply inner stylesheets. If not included, inner<style>
and<link rel="stylesheet">
elements have no effect.
The default, to match today's behavior, is styleOrder: "inner adopted"
. My problem would be addressed via styleOrder: "outer adopted inner"
.
Yes, this is intentionally immutable. It needs to be for perf reasons.
Yes, this allows disabling CSS customization entirely. But that's not the point, and I'm intentionally not proposing a way to disable scripting here.
For declarative shadow DOM, styleOrder
can be specified via shadowrootstyleorder="..."
.
Anything else?
This addresses one of the big impediments to prerendering web components in my experience.