Reputation: 191
I am developing a product using Laravel + Svelte + materializecss.
I use Svelte components as custom tags using svelte: options
.
Example:<svelte: options tag = "custom-tag" />
If you try to load materializecss within this component, It must run import every time in the component. The parent HTML calls materializecss.
Why is this? I would appreciate it if you could tell me.
index.blade.php
<html>
<head>
<!-- ↓ materializecss included -->
<link rel="stylesheet" href="/css/app.css">
</head>
<body>
<custom-tag />
<script src="js/app.js"></script>
</body>
</html>
CustomTag.svelte
<svelte:options tag="custon-tag"/>
<style>
/* Why is this essential? */
@import 'https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/css/materialize.min.css';
</style>
<p>This is test.</p>
Upvotes: 1
Views: 1428
Reputation: 16451
When using custom element, the element itself will be rendered in something called the "Shadow DOM", this is a piece of dom that is rendered in your page, but is not really part of the entire DOM structure of the page itself, this means that for instance you cannot use JavaScript outside of this Shadow DOM to manipulate individual elements inside the Shadow DOM. This works both ways by the way: code inside the Shadow cannot affect elements outside of it, except through it's public interface.
Read more on MDN - Using shadow DOM for details (it's not as black and white as I describe above)
This also applies to CSS, your global style rule stops at the border of the Shadow DOM and is not applied to anything inside the Shadow. This is why you need to import the materialize css in the element itself.
The Svelte documentation says this about it:
Styles are encapsulated, rather than merely scoped. This means that any non-component styles (such as you might have in a global.css file) will not apply to the custom element, including styles with the :global(...) modifier.
Instead of being extracted out as a separate .css file, styles are inlined into the component as a JavaScript string
Depending on how the imported CSS is written, it might or might not mean that a lot of it is added to your element (not sure if it is treeshake-able) to make your component lighter you might need to cherry-pick parts of your larger css import or at least extract only those parts you need.
Upvotes: 4