Re: [w3ctag/design-reviews] Declarative CSS Modules and Declarative Shadow DOM `adoptedstylesheets` attribute (Issue #1000)

dandclark left a comment (w3ctag/design-reviews#1000)

I'm posting the following on behalf of the TAG. Authorship credit for the comment largely goes to @jyasskin who is on vacation for the next week and a half but who drafted the bulk of it prior to leaving.

------

Thanks everyone for looking into the `@sheet` design space and then bringing this back to us when it didn't work out. We agree that @justinfagnani's constraints in https://github.com/w3ctag/design-reviews/issues/1000#issuecomment-3076124488 need to be met by any reasonable solution and that it's important to solve this, even if we have to accept a design that's less [theoretically pure](https://www.w3.org/TR/design-principles/#priority-of-constituencies).

We have a bunch of thoughts and questions about the details. We suspect specifiers and integration with the module map is going in the right direction, but we want to check that they integrate well and that you've fully explored a couple other options.

On @sorvell's point that ["@import cannot be used in a constructed stylesheet."](https://github.com/w3ctag/design-reviews/issues/1000#issuecomment-3076091602), we agree that's a problem, but we think it can be solved independently of this design, so we won't consider it further here.

### On the explainer

It would be good for the explainer to show the HTML for the sort of component nesting that requires the proposed solution. We're working from @jyasskin's example in https://github.com/w3c/csswg-drafts/issues/11509#issuecomment-2651701885, but there should be a canonical example in the explainer.

Showing [specifiers like `/foo.html`](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/ShadowDOM/explainer.md#other-declarative-modules)  makes it look like a document is trying to claim parts of the URL space, but we don't think that's what you're actually proposing. Please avoid showing specifiers like this, or if it's the intention to allow these to behave like URLs, make that clear and detail how it's expected to work.

### Details to flesh out

Please describe how this integrates with the module map and with importmaps in more detail. We assume it'll be possible to assign specifiers with either `<style type="css-module" specifier="bar">` or `<script type="importmap">{"imports": {"bar": "./foo.css"}}</script>` and use them with either `adoptedstylesheets=bar` or `import styles from 'bar' with { type: 'css' };`, but you should say it explicitly. Is `specifier` truly just a shorthand for an adjacent importmap, or does it do something more?

Was it ever intentional that `<script type="importmap">` works inside a shadow root? It'd be good to check with that feature's designers (e.g. @domenic) to ensure that encouraging its use there won't break any assumptions or encourage any footguns.

### Alternatives to consider

It sounds like the fundamental difference between `<link rel=stylesheet>` and `adoptedstylesheets` is whether the sheets are applied by value or by reference. (And when they're applied by reference they appear in the `adopedStylesheets` JS list.) Please look for ways to make the syntaxes more similar, for example by giving `<link rel="adopt stylesheet">` the by-reference semantics. This may need to define a way for `<link>` elements to refer to into the module map instead of just to URLs, which might or might not be the `href` attribute.

As described in https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/ShadowDOM/explainer.md#scoping and in @justinfagnani's requirements, it's important to be able to name things across shadow boundaries. The easiest way to do that is to use a global mapping like the module map, but [as we saw with the custom element registry, we often find a later need to scope that global object](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Scoped-Custom-Element-Registries.md). What if, instead, we defined a way to name style elements or `@sheet`s across shadow boundaries? `open` shadow roots could be pierced explicitly from the outside, perhaps by using a `#id-of-host:~:within-shadow=id-inside-shadow/id-inside-that-host`. (`/` might not be the best way to traverse multiple levels, and `:~:` is from [text fragments](https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Fragment/Text_fragments).) `closed` shadow roots need to explicitly export the relevant elements, and [phase 1 of `referenceTarget`](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/reference-target-explainer.md) probably isn't flexible enough. It might be reasonable just to postpone handling `closed` shadow roots. This might turn out to be too complex, but you ought to explore the possibility.

Because the current `specifier` attribute does expose its element across shadow boundaries, it might be better to name it in a way that flags this behavior. Perhaps `exportspecifier`.

### Changes you should probably make

You have [`adoptedstylesheets` taking a comma-separated list of specifiers](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/ShadowDOM/explainer.md#proposal-inline-declarative-css-module-scripts), but we have a design principle that [it should be space-separated](https://www.w3.org/TR/design-principles/#html-lists).

-- 
Reply to this email directly or view it on GitHub:
https://github.com/w3ctag/design-reviews/issues/1000#issuecomment-3162121691
You are receiving this because you are subscribed to this thread.

Message ID: <w3ctag/design-reviews/issues/1000/3162121691@github.com>

Received on Thursday, 7 August 2025 01:28:45 UTC