Using SCSS variables in Angular
When creating a new project using Angular CLI you can choose to have SCSS support in the project preconfigured. But even if you do, it doesn't set up any file for the rules that will be reused across components (such as variables, functions, and mixins).
Usually, I don't even need it. My mixins and functions are typically local to a single component SCSS file. And instead of SCSS variables, I use CSS3 variables. These I can put in the styles.scss
file:
:root {
--color-text: #111111;
--color-link: #125699;
}
I can then use the variables in any component SCSS file:
.title {
color: var(--color-text);
}
.link {
color: var(--color-link);
}
Since the browser processes the CSS3 variables, this works. The build process is only responsible for including the styles.scss
file in the web page.
I recently worked on a project which had to work in older browsers without support for CSS3 variables. To make the project compatible with them, I decided to replace all my CSS3 variables with SCSS variables.
I could make most of the changes using the replace functionality in the editor:
For the variable declarations, I removed the
:root
selector and replaced--
with$
:$color-text: #111111; $color-link: #125699;
The syntax for using these variables had to be changed to the following:
.title { color: $color-text; } .link { color: $color-link; }
To automate the conversion, I had to use VS Code's regular expression support in search and replace:
- Search string:
var\(--(.*)\)
. There are parentheses around the part matching the variable name so that I can reference it in the replace string as group 1. - Replace string:
$$$1
. The$$
part results in a single$
character in the output. The$1
references the first (and only) group in the search regular expression.
The preview window helps a lot to get the syntax right:
After doing all that, the Sass compiler emitted an error:
SassError: Undefined variable.
The compiler processes each file individually and therefore doesn't know about the variables. The @import
statement can be used to include declarations from another file:
@import "../../vars";
Since I had regular CSS styles in my styles.scss
file, which I didn't want to duplicate by including it in other files, I created a separate vars.scss
file containing only the variable declarations. These don't emit any CSS after compilation, so there's no danger of duplicate rules if the file is included multiple times.
You can check my GitHub repository to see the changes when switching from CSS3 variables to SCSS variables.
Although there are functional differences between CSS3 and SCSS variables, you can convert the former to the latter with an almost fully automated process if your use case is simple enough.