Notes

CSS variables (custom properties) vs. Sass variables

Edit on GitHub

CSS & Sass
3 minutes

tl;dr

Sass variables

  • can not be manipulated in JavaScript
  • do not work for media query values
  • sass variables, when re-assigned values, do not update all instances of that variable with the new value. if a value has been assigned, and used, 3 times before being assigned a 4th time, you will have 4 different values for the same $variable. (Example code below referenced from the Sass docs)

CSS variables

  • do not work in Sass color functions

CSS custom properties are much more powerful than pre-processor ones, as they can be changed at runtime with javascript and be used in all sorts of awesome ways, but when you’re using them as regular variables, pre-processor variables are always better for compatibility. ref

Here’s an excerpt on the difference between the two from the Sass documentation on variables:

CSS has variables of its own, which are totally different than Sass variables. Know the differences!

  • Sass variables are all compiled away by Sass. CSS variables are included in the CSS output.
  • CSS variables can have different values for different elements, but Sass variables only have one value at a time.
  • Sass variables are imperative, which means if you use a variable and then change its value, the earlier use will stay the same. CSS variables are declarative, which means if you change the value, it’ll affect both earlier uses and later uses.
 1$color-text: black;
 2
 3h1 { color: $color-text; }
 4h2 { color: $color-text; }
 5h3 { color: $color-text; }
 6
 7$color-text: purple;
 8
 9h4 { color: $color-text; }
10h5 { color: $color-text; }
11h6 { color: $color-text; }

will generate

1h1 { color: black; }
2h2 { color: black; }
3h3 { color: black; }
4h4 { color: purple; }
5h5 { color: purple; }
6h6 { color: purple; }

Screenshot - Sass variables are imperative

h1, h2, h3 will be black, and h4, h5, h6 will be purple.

Whereas the following CSS code with CSS custom properties

 1:root { --color-text: black; }
 2
 3h1 { color: var(--color-text); }
 4h2 { color: var(--color-text); }
 5h3 { color: var(--color-text); }
 6
 7:root { --color-text: purple; }
 8
 9h4 { color: var(--color-text); }
10h5 { color: var(--color-text); }
11h6 { color: var(--color-text); }

will result in

1h1 { color: purple; }
2h2 { color: purple; }
3h3 { color: purple; }
4h4 { color: purple; }
5h5 { color: purple; }
6h6 { color: purple; }

Screenshot - CSS variables are declarative

All links will be purple.

This difference between imperative and declarative matters when you’re building themes and typography systems