Setting CSS values dynamically in Svelte
If you are used to React's Styled Components, assigning CSS values dynamically in Svelte can be baffling at first.
CSS-in-JS is not universally popular. In fact many developers, expecially CSS experts, absolutely detest it, as the CSS gets lost in a sea of JS. Although in Svelte CSS is parsed and rendered by JS, the framework actually tries to keep the two separate. You cannot plug JS values into CSS; the following will not work
<!-- App.svelte-->
<script></script>
<style>
div {
grid-template-cols: 1fr 2fr;
grid-template-areas: 'nav main';
}
</style>
<div>
<OneComponent gridArea={nav}>
<AnotherComponent gridArea={main}>
</div>
<!-- AnotherComponent.svelte -->
<script>
export let gridArea;
</script>
<style>
div { grid-area: {gridArea}; }
</style>
<div>
Welcome to my homepage
</div>
This looks a bit drastic. What if you need to pass some CSS values down the component tree? Well it’s doable - you just need to use CSS variables, and use the HTML section of your .svelte file as a sort of free trade zone where JS and CSS can talk to each other
<!-- AnotherComponent.svelte -->
<script>
export let gridArea;
</script>
<style>
div {
grid-area: var(--grid-area);
}
</style>
<div style="--grid-area: {gridArea}">Welcome to my homepage</div>
So the component gets the value injected into a JS variable, which is then copied into a CSS variable in one of the HTML elements’ style attributes. Doesn’t matter which one, apparently. It’s a bit of a roundabout way, and it’s not clear how conflicts are dealt with, but it keeps the CSS nice and neat, which is a good thing.