Should there be a declarative version of adoptedStyleSheets?
Once declarative Shadow DOM is a thing, it would be very nice to be able to declaratively specify a (shared) adoptedStyleSheets value, by reference. This would avoid the need to repeat <style> or <link> tags for each declarative Shadow Root.
It would seem that several things are needed here:
- A declarative syntax for a stylesheet. This is likely just a
<style>tag with an id. - A way to refer from one location (e.g. a declarative Shadow Root) to another stylesheet, which potentially resides across document/shadow bounds. This likely requires something like WICG #169.
What other ideas are there for how to add adoptedStyleSheets support to declarative Shadow DOM?
why wouldn't a <link rel="stylesheet" href="shared.css"> within a declared Shadow DOM implicitly be used/adopted as style for such Shadow DOM?
why wouldn't a
<link rel="stylesheet" href="shared.css">within a declared Shadow DOM implicitly be used/adopted as style for such Shadow DOM?
That (or an enclosed <style> tag) is the current recommended best practice for declarative Shadow DOM. In this case, the stylesheet wouldn't be used as an adoptedStyleSheet, but it would be added to shadowRoot.styleSheets. And further, most/all browsers optimize away repeated such <link> or <style> tags to point to a single, shared (copy on write) instance of a StyleSheet.
The downsides of this approach, which this issue tries to tackle, are:
- The overhead of sending repeated copies of
<style>tags, or fetches for small<link>stylesheets. - The fact that these shared stylesheets are only "copy on write" shared. Changing one of them does not change all of them, in contrast to
adoptedStyleSheets.
To take a step back, is the problem reusing a style sheet across distinct shadow trees or is the problem reusing a shadow tree? The latter is the concern I heard @fantasai raise during the meeting.
To take a step back, is the problem reusing a style sheet across distinct shadow trees or is the problem reusing a shadow tree? The latter is the concern I heard @fantasai raise during the meeting.
Both of these concerns were raised at the meeting, but this issue is about the former: re-using styles.
The latter, re-using shadow trees, is (much!) better solved by Template Instantiation, in my opinion. Declarative Shadow DOM is just like the rest of HTML - if you want two identical chunks of DOM, copy/paste the HTML for them. Or use templates (or template instantiation) to stamp out copies of HTML.
The downsides of this approach, which this issue tries to tackle, are...
Aren't <link>s also async when outside of the head, so using a link tag in DSD produces FOUC? Or no?
Note that @justinfagnani proposed something for this a while back here: https://github.com/WICG/webcomponents/issues/939
@mfreed7 I was reading through your comment above and I'm not sure I understand how this meaningfully differs from a <link> tag.
I understand that this (1) helps avoid duplication of <style> tags, (2) helps avoid making unnecessary fetches for small stylesheets that would be better inlined, and (3) can adapt to changes made to <style> tags. But I'm unclear on the benefit of this vs larger external stylesheets that rarely change (if ever).
Here’s an idea for what this might look like.
Inline CSS module:
<style type="module">
p { color: hotpink; }
</style>
External CSS module:
(maybe this should be <link>?)
<style type="module" src="external.css"></style>
By default it should be adopted by the document (into document.adoptedStyleSheets).
But if these CSS modules are included inside declarative shadow DOM, then they would be automatically adopted by the shadow root.
And then ideally there’s a declarative way to instantiate templates, which could be reused to also share CSS modules across shadow-roots (and with the document too).
Hypothetical HTML module syntax
<template type="module" id="foo">
<style type="module" src="external.css"></style>
<slot></slot>
</template>
<my-component>
<template shadowrootmode="open" from="foo"></template>
<p>Hello</p>
</my-component>
If declarative shadow DOM requires repetition, then it's probably fine for declarative adopted stylesheets to also do the same. A proper solution for template reuse can solve repetition of HTML/CSS together in the future and independently of this particular issue.
Edit: @sheet looks related as well.