CSS Custom Properties in Sass

TL;DR

Use --my-var: #{$my-sass-variable}; to be able to use Sass variables as values for CSS Custom Properties.

The problem

Let’s say you have the following SVG of a circle with an exclamation mark that you want to inline in your markup.

<svg height="48" width="48" viewBox="0 0 48 48">
  <circle fill="currentColor" cx="24" cy="24" r="20" />
  <rect fill="#fff" x="21" y="10" width="6" height="18"
      style="fill: var(--fill, #fff)" />
  <circle fill="#fff" cx="24" cy="35" r="5"
      style="fill: var(--fill, #fff)" />
</svg>

If you want to change just one colour, in this case the circle, you can use a fill attribute with currentColor as its value. This allows you to change the background colour of the circle using SCSS, like so:

1$dark-blue: #ff1493;
2
3svg {
4  color: $dark-blue;
5}

This works perfectly fine but it is limited to just one colour. CSS Custom Properties can help if you wanted to change more than just one colour.

The <rect /> and the second <circle /> in the SVG above have their fill attribute set to white (#fff). In modern browsers this can be overriden using CSS Custom Properties. The style attribute in the SVG above uses a custom property --fill that can be given a value in SCSS to apply a different fill colour 1. In SCSS it looks like this, but unfortunately this does not work.

1$dark-blue: #ff1493;
2$yellow: #800080;
3
4svg {
5  color: $dark-blue;
6  // this does not work as expected
7  --fill: $yellow;
8}

What ended up in the browser was the following:

svg {
  color: #ff1493;
  --fill: $yellow;
}

This obviously does not work and resulted in a black exclamation mark on a dark blue background instead of the yellow exclamation mark that was expected.

In order to get this to work we need to use Sass’s interpolation #{} like so:

1$dark-blue: #ff1493;
2$yellow: #800080;
3
4svg {
5  color: $dark-blue;
6  --fill: #{$yellow};
7}

Et voilá, a beautiful multicolour SVG with proper fallback in browsers that do not support Custom Properties.

Ok, so maybe not yellow on dark blue, but still pretty.


  1. It also still has a fallback value of #fff in case the variable was not set in the CSS of a browser that supports CSS Custom Properties. ↩︎