Geoff Rich
Posted on April 28, 2022
Svelte has a built-in solution for component theming using style props. So, you can use CSS custom properties in your component styles...
<p>
I have something important to say.
</p>
<style>
p {
border: 2px solid var(--line-color);
/* Decorative styles */
padding: 1rem;
max-width: 60ch;
}
</style>
...and easily set them from outside the component using style props.
<TextBox --line-color="mediumspringgreen"></TextBox>
But what if you want your style to have a default value? The custom property var
syntax takes a second argument that sets a fallback if the property is not defined. So, if you wanted the default border color to be darkred
, you could do the following.
p {
border: 2px solid var(--line-color, darkred);
}
However, this can get verbose if you want to use --line-color
in multiple places, with the same fallback. If you want to update the default value, you have to do it multiple places!
p {
border: 2px solid var(--line-color, darkred);
text-decoration: underline wavy var(--line-color, darkred) 1px;
}
There’s two ways to refactor this to make it less verbose. First, you could introduce another custom property for the default value:
p {
--line-color-default: darkred;
border: 2px solid var(--line-color, var(--line-color-default));
text-decoration: underline wavy var(--line-color, var(--line-color-default)) 1px;
}
This makes it so there’s one place to change the default value, but you still have to provide the second argument to var
every time you reference --line-color
.
Instead, my recommended approach would be to introduce another custom property that represents either line-color or the fallback.
p {
--_line-color: var(--line-color, darkred);
border: 2px solid var(--_line-color);
text-decoration: underline wavy var(--_line-color) 1px;
}
So now you have two variables:
-
--line-color
is the user-supplied theme value -
--_line-color
is what we use in our styles, and will either be the user-supplied value (if defined) or the default color
You can see this in action in this Svelte REPL.
You only need to introduce a variable like --_line-color
if you plan on using the theme variable multiple places. Otherwise, it’s perfectly fine to set the fallback where you use the property, as in the first example.
The technique on display here is not unique to Svelte, and can be applied anywhere you use custom properties. However, it's of particular interest with Svelte, since custom properties are the recommended way of theming a component.
Posted on April 28, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.