CSS Vars or SASS Vars? Use both!

Frank Lämmer
Teutonic CSS
Published in
3 min readAug 15, 2018

--

So, the correct title here would be: “Should I use CSS Custom Properties or variables from a CSS preprocessor such as SASS, LESS or Stylus? Use both!”

Motivation

I see some hype about CSS Vars lately, which I like, because I am the biggest fan boy here. But I also read, that now with CSS Vars you might not need your old SCSS Vars any more? While I sometimes dream at night to write pure CSS without a build script I tend to think something else for my daytime life: CSS Vars and SCCS Vars, best use both in combination. Here is the long story:

CSS Vars are exposed

One great advantage of the new native CSS Vars is, that they live in your browser. The are fully accessible. You can inspect them. And maybe most importantly manipulate them (with Javascript).

Skinnable properties

:root {
--font-body: Constantia;
--font-headline: -system;
--text-base: 1em;
--text-ratio: 1.25;
--color-prime-3: blue;
}

Teutonic CSS (my great new CSS framework) uses CSS Vars for skinning. That way you can include a minified CSS file but you are still able to override the most important settings to theme and customize the look. You can define sizes, colors and typefaces.

My Tip: CSS Vars are the first choice. Use them for any style settings that can and should be accessible.

SASS Vars are hidden

The preprocessors variables are living in the shadows. They are unaccessible and invisible. And that is good. You likely will have parts in your code, that are not meant for public or production. That’s why using two types of CSS variables in one project makes perfect sense. Let me show you some examples from Teutonic CSS (the great new …) where I use SCSS variables instead of CSS variables:

Presets

$double-octave    : 4            ;
$pi : 3.14159265359;
$major-twelfth : 3 ;
$major-eleventh : 2.666666667 ;
$major-tenth : 2.5 ;
$octave : 2 ;
$major-seventh : 1.875 ;
$minor-seventh : 1.777777778 ;
$major-sixth : 1.666666667 ;
$phi : 1.618034 ;
$golden : $phi ;
$minor-sixth : 1.6 ;
$fifth : 1.5 ;
$augmented-fourth : 1.41421 ;
$fourth : 1.333333333 ;
$major-third : 1.25 ;
$minor-third : 1.2 ;
$major-second : 1.125 ;
$minor-second : 1.066666667 ;

This is just a (stolen) list of defaults. It’s optional to use them but nice to know that they are there. Only one of these values might or might not be used in the end. So it is intended that those don’t show up in the final CSS file.

Switch

@if $type-calc == "css" {
--text-m : calc(var(--text-ratio) * var(--text-s));
--text-s : calc(var(--text-ratio) * var(--text-xs));
} @else {
--text-m : #{$text-m};
$text-s : $text-m / $text-ratio;
--text-s : #{$text-s};
}

With Teutonic CSS, the modular scale of text is done live in the browser per default. That’s cool, but might cause performance issues. Therefore there is a switch to change the build process to use classical values.

Color map

Even more readable and extendible for me is, to have the colors stored in SCSS color map first:

$colors: (
main: (
1: hsl( 65, 12%, 95%),
2: hsl( 65, 12%, 90%),
3: hsl( 65, 12%, 55%),
4: hsl( 65, 12%, 25%),
),
prime: (
1: hsl(250, 30%, 95%),
2: hsl(250, 60%, 90%),
3: hsl(250, 99%, 70%),
4: hsl(250, 80%, 45%),
)
);

And then later on feed the CSS Vars for colors from that file:

:root {
@each $name, $color in $colors {
@each $index, $value in $color {
--#{$name}-#{$index}: #{$value};
}
}
}

Media breakpoints

Unfortunately it is not possible to media query breakpoints in `:root`. So your preprocessor is the next best fallback.

My Tip: SASS vars are here to stay. Combine CSS Vars and SCSS to get best of both worlds.

--

--