-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
render Svelte components inside shadow dom #5869
Comments
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
In 3.40.0, you can now specify a |
Doing so requires compiling _all_ components as custom elements, which for some reason makes child components quite slow in some naive testing. Would like to revisit if sveltejs/svelte#5869 is resolved.
This problem still exists for me in version 3.50.1. When rendering Svelte inside a shadow dom, the styles are appended to document.head of the html element outside the shadow dom even when using a shadow dom element as target. am I missing something here? |
@Obehi, check out the #5870 (comment). You need to pass // suppose you are using vite and vite-plugin-svelte
import { svelte } from '@sveltejs/vite-plugin-svelte'
export default {
plugins: [
svelte({
emitCss: false,
}),
]
} |
Nice, this resolves Svelte styles! What about css imports? Is there any way to make sure they're also attached in the same component rather than going to head? |
We've created a function for wrapping a Svelte component in a web component and mounting it in a FWIW, this is our wrapper: |
If you take a look at the version 4 milestone, you see that a lot of issues relate to the I was also wondering why Svelte maintains two different build outputs. In the end a wrapper at the entry point should be good enough. |
You can do something like this to scope imports to the shadow root. import Component from 'Component.svelte';
import css from './theme.css?inline';
const shadowRoot = document.body.attachShadow({ mode: "open" });
shadowRoot.innerHTML = `<style>${css}</style>`;
new Component({ target: shadowRoot }); |
Shadow method works well. Here is how I did it: // create a shadow dom container to prevent css conflicts from the page
const container = document.createElement("shadow-dom-container");
const shadowRoot = container.attachShadow({ mode: "open" });
document.body.appendChild(container);
// fonts should be loaded in the page
const fontStyle = document.createElement("style");
fontStyle.innerHTML = `@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap');`;
document.head.appendChild(fontStyle);
const comp = new MySvelteComponent({
target: shadowRoot,
props: {
...
},
});
|
Currently it is difficult to take advantage of the style encapsulation from the shadow dom when using Svelte.
The problem is that Svelte always appends styles to
document.head
. When your component is renderen into a shadow dom, the styles will be appended outside the shadow root and therefore will have no effect in your Svelte-Application.There are already ways to use Svelte in a shadow dom - however, they all have their drawbacks:
customElement: true
compiler option:There are some important differnces: see Custom element API from the official Svelte docs.
I already tried this approach. It worked great until I started caching the ressources. It sometimes happened that the new js file was loaded with the old css file (yes, I have set both cache headers the same). In the new js file, all class-hashes were different and so no styles could be applied.
I have developed a tool that renders an overlay on any given Website. In my use case style encapsulation is necessary to deliver a good-looking product. I already have tried a few workarounds to increase the specificity of my css-selectors:
!important
on every style definition.It was working for most Websites but still, every few weeks I encountered a new Issue, where the styles of the website was overriding the styles of my overlay. The size of my bundle was uneccessary bigger and it also made it impossible to use the svelte-animations, due to the high specificity of my style selectors.
I came to I point where I have given up on building workarounds.
It would be really helpful for use-cases like this to be able to render a Svelte application inside a shadow dom.
The text was updated successfully, but these errors were encountered: