Svelte quick tip: Style prop defaults

geoffrich

Geoff Rich

Posted on April 28, 2022

Svelte quick tip: Style prop defaults

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>
Enter fullscreen mode Exit fullscreen mode

...and easily set them from outside the component using style props.

<TextBox --line-color="mediumspringgreen"></TextBox>
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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.

💖 💪 🙅 🚩
geoffrich
Geoff Rich

Posted on April 28, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related