- From: Jeffrey Yasskin <notifications@github.com>
- Date: Thu, 04 Sep 2025 09:50:42 -0700
- To: w3ctag/design-reviews <design-reviews@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <w3ctag/design-reviews/issues/1000/3254588565@github.com>
jyasskin left a comment (w3ctag/design-reviews#1000) Thank you for the replies and explainer updates. We think you're on the right track and are updating our resolution to `satisfied`. We have a list of details that we think the relevant working groups should keep paying attention to as this design gets fleshed out into a final specification: * The choice of `shadowrootadoptedstylesheets="bar"` or `<link rel="adoptedstylesheet" specifier="foo">` for adopting a stylesheet by specifier. We're not sure that media queries are really a win for `<link>`: you'd probably want to do the query once in the `<style type=module>` instead of on each import. But it might be useful to have `<link rel="adoptedstylesheet" href="./url.css">` guarantee a single object that's modifiable by reference. * Should the `rel` be `"adoptedstylesheet"` or `"adopt stylesheet"`? There are probably backward-compatibility implications that we haven't thought through. * The discussion of [future work on other declarative modules](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/ShadowDOM/explainer.md#other-declarative-modules) is really useful to inform this choice. * It may also be worth using simply `<template shadowrootmode="..." adoptedstylesheets="...">` to make the attribute easier to read. We see why you're prefixing these, but HTML has a history of short-named attributes that only apply to some modes of their element, in the `<link>` element at least. * The naming of the `specifier` property, both for export (`<style type=module specifier=...>`) and import (`<link rel="adoptedstylesheet" specifier="foo">`). Those don't have to be the same: export should perhaps be `exportspecifier`, and import could use `<link import="foo">`. * Whether `shadowrootadoptedstylesheets` should be able to adopt a non-inline stylesheet, either via: ```html <script type="importmap"> { "imports": { "my-styles": "./styles.css", } } </script> <script type="module"> import style from "my-styles" with { type: "css" }; </script> <template shadowrootmode="open" shadowrootadoptedstylesheets="my-styles"> ... </template> ``` or directly via ```html <template shadowrootmode="open" shadowrootadoptedstylesheets="./styles.css"> ... </template> ``` `"./styles.css"` may still be pending at the time that a shadow tree is created from the `<template>`, which creates a risk of FOUC. This might be a reason to prefer importing with `<link>` so developers can use its existing `load` event to manage asynchronous loading. It might also be possible to use the [`<link blocking>` attribute](https://html.spec.whatwg.org/multipage/urls-and-fetching.html#blocking-attributes) to indicate that the shadow tree should only be created when the style is ready. * Might the detailed semantics be easier to understand if they acted as syntactic sugar? For example, ```html <style type="module" specifier="foo"> #content { color: red; } </style> ``` could be syntactic sugar for ```html <script type="importmap"> { "imports": { "foo": "data:text/css,<content of the style block>" } } </script> ``` And ```html <template shadowrootmode="open" shadowrootadoptedstylesheets="foo ./styles.css">...</template> ``` could be sugar for ```html <script type="module"> const shadowRoot = host.attachShadow({mode: 'open'}); import("foo", {with:{ type: "css" }}).then(foo=>shadowRoot.adoptedStyleSheets.push(foo)); import("./styles.css", {with:{ type: "css" }}).then(styles=>shadowRoot.adoptedStyleSheets.push(styles)); </script> ``` This probably sacrifices the ability to write the `<style type=module` after the `<template>` that adopts it, but streaming SSR can probably emit the style block just before adopting it. How important is this ability? This also re-allows writing `<style type="module" specifier="./styles.css">`, which [we previously discouraged](https://github.com/w3ctag/design-reviews/issues/1000#issuecomment-3162121691), but we now think it's ok as long as it's clear that this is defining a specifier the way importmaps already allow, and not trying to change what `fetch('./styles.css')` or `window.location='./styles.css'` might do. * @domenic's [comment](https://github.com/whatwg/html/issues/10673#issuecomment-3222362601) includes several more good things to keep paying attention to as the design gets fleshed out. * We agree that this needs to extend naturally to JSON modules, but it also seems like there's at least one natural way to do that, so we're not worried about it. * Domenic's concern about how to store these modules might be satisfied by the above suggestion to store them as `data:` URLs. * We agree that care will be needed when referring to these specifiers from HTML attributes. What design principle could we write about when it's appropriate to create each kind of attribute? How can we signal to developers which attributes take which of these similar types? When it's appropriate for an attribute to take a specifier, the design space includes both: 1. Adding a new attribute whose value space is specifiers, and 2. Modifying an existing attributes whose value space is currently URLs, to change it so that its value space is now specifiers. (b) is obviously risky, but there may not be any existing pages whose meaning would change, so we should consider it if it'll make the future state easier to understand. * We're less worried than Domenic about allowing `<link>` to refer to (indirect) specifiers in addition to (direct) URLs. With inline modules stored as `data:` URLs, `<link>` does always resolve to a URL, just perhaps not one written literally in the source. -- Reply to this email directly or view it on GitHub: https://github.com/w3ctag/design-reviews/issues/1000#issuecomment-3254588565 You are receiving this because you are subscribed to this thread. Message ID: <w3ctag/design-reviews/issues/1000/3254588565@github.com>
Received on Thursday, 4 September 2025 16:50:46 UTC