Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should there be a declarative version of adoptedStyleSheets? #910

Open
mfreed7 opened this issue Oct 28, 2020 · 10 comments
Open

Should there be a declarative version of adoptedStyleSheets? #910

mfreed7 opened this issue Oct 28, 2020 · 10 comments
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: shadow Relates to shadow trees (as defined in DOM)

Comments

@mfreed7
Copy link
Contributor

mfreed7 commented Oct 28, 2020

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:

  1. A declarative syntax for a stylesheet. This is likely just a <style> tag with an id.
  2. 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?

@WebReflection
Copy link

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?

@mfreed7
Copy link
Contributor Author

mfreed7 commented Oct 28, 2020

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:

  1. The overhead of sending repeated copies of <style> tags, or fetches for small <link> stylesheets.
  2. 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.

@annevk
Copy link
Member

annevk commented Oct 29, 2020

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.

@annevk annevk added addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: shadow Relates to shadow trees (as defined in DOM) labels Oct 29, 2020
@mfreed7
Copy link
Contributor Author

mfreed7 commented Oct 30, 2020

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.

@matthewp
Copy link

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?

@matthewp
Copy link

Note that @justinfagnani proposed something for this a while back here: WICG/webcomponents#939

@mayank99
Copy link

@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).

@mayank99
Copy link

mayank99 commented Mar 17, 2024

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.

@Westbrook
Copy link

Helping to close the circle: https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/ShadowDOM/explainer.md

cc: @dandclark

@patrick-mcdougle
Copy link

patrick-mcdougle commented Oct 9, 2024

I ran into a performance issue today where I have 100 cards in a grid, and each card mounts a webcomponent with shadow containing a <link> tag. I discovered that while the browser is smart enough to coalesce the network calls, it seems to have to construct 100 distinct CSSStyleSheets which created a 300ms parseStylesheet/computeLayout/GC when the resource came back from the network. IMO the browser should be able to create 1 CSSStyleSheet and attach it to all 100 of the shadowTrees instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: shadow Relates to shadow trees (as defined in DOM)
Development

No branches or pull requests

7 participants