Styles not being properly imported when using shadow DOM
Opened this issue · 3 comments
This is currently low priority for me personally (since I do not use the shadow DOM), but welcome a PR to fix this if anyone is interested and has the time. The only reason I think it's still worthwhile to consider supporting shadow DOM is because it brings some important svelte-retag
specific features to existing capability in Svelte, i.e.
- Vite HMR compatibility
- Composability (i.e. easily use normally internally within Svelte + the ability to define custom elements as needed)
🤔 FWIW, it appears that this affects the original fork svelte-tag
as well. Anyway, see below.
Describe the bug
Styles from the component itself work fine in light DOM, but when using shadow DOM (at least in development mode) the CSS styles from the component do not appear to be injected at all into the component.
Reproduction
JavaScript
import svelteRetag from 'svelte-retag';
import HelloWorld from './HelloWorld.svelte';
svelteRetag({ component: HelloWorld, tagname: 'hello-world', shadow: true });
HTML
<hello-world></hello-world>
Svelte component
<div>Hello world</div>
<style>
div {
border: 1px dotted red;
}
</style>
Logs
No response
System Info
System:
OS: Linux 5.15 Debian GNU/Linux 11 (bullseye) 11 (bullseye)
CPU: (16) x64 Intel(R) Core(TM) i7-10875H CPU @ 2.30GHz
Memory: 2.26 GB / 5.79 GB
Container: Yes
Shell: 5.1.4 - /bin/bash
Binaries:
Node: 16.14.2 - ~/.nvm/versions/node/v16.14.2/bin/node
Yarn: 1.22.19 - ~/.nvm/versions/node/v16.14.2/bin/yarn
npm: 8.5.0 - ~/.nvm/versions/node/v16.14.2/bin/npm
Browsers:
Chrome: 111.0.5563.146
npmPackages:
svelte: ^3.57.0 => 3.58.0
svelte-retag: ^0.0.3 => 0.0.7
Severity
annoyance
Note: This may actually only affect IIFE-based execution which embeds styles in the JS and then tries to attach them to the main document. If compiling using the typical modules, you can still pass the generated CSS as an argument to the href
property in setup.
Probably related to vitejs/vite#11769. Maybe just specific to compiling to umd
or iife
in Vite, causing the styles to be injected on the host page instead of making them available in the shadow DOM.
Reverting title again, since there are actually multiple use cases for this (i.e. missing styles when using the shadow DOM):
- IIFE/UMD: As noted above, styles are always only ever attached to the root document
- Dev mode: When in dev mode (which always uses modules), it's not practical to reference a built CSS. However,
<style>
tags for each component are still attached individually to the root document dynamically by Vite (available with a specialdata-vite-dev-id
attribute).
This issue could be an opportunity to approach resolving both at the same time. Uncovered when validating both light + shadow DOM fixes for issue #10. Some ideas on resolving:
- IIFE/UMD:
- Maybe build and then require some kind of preprocessor plugin? No idea yet. The style cloning approach below (for dev mode) could work, however it seems far too crude for production.
- Dev mode:
- Augment the API to allow user to also opt into dynamically cloning
<style data-vite-dev-id>
tags on the document and also appending them toshadowRoot
's. Possibly hacky, but might work since it appears that (at least with the default configuration), styles are still scoped even within the shadow DOM, so conflicts may not arise (but could). - Also utilize a preprocessor of some sort to redirect styles to some kind of scope that svelte-retag has access to and can redirect appropriately?
- Augment the API to allow user to also opt into dynamically cloning