DEV Community

Cover image for Forget about SCSS variables
Maksim Dolgih
Maksim Dolgih

Posted on • Originally published at Medium

Forget about SCSS variables

SCSS variables

In my career, I’ve managed to work on a lot of projects that used styling via SCSS, LESS, or Stylus. One of the main advantages of favoring them over CSS, besides “cascading”, was “variables

They enabled:

  • To respect the DRY principle

  • To centralize shared variables for reuse via @import or @use

  • To create more abstract styles without hardcoding

  • To synchronize variable names with Figma tokens

  • To perform simple arithmetic and complex operations on variables

  • Variables did not go directly into the build, but were compiled into actual CSS values

Example of implementation

Let’s realize a basic example of SCSS variables application

Variables

    $primary: #d75894;
    $secondary: #9b3dca;
    $background: #fafafa;
Enter fullscreen mode Exit fullscreen mode

Styling of elements

    @use 'variables';


    body {
     background: variables.$background;


     h1 {
       color: variables.$primary;
     }


     p {
       color: variables.$secondary;
     }
    }
Enter fullscreen mode Exit fullscreen mode

Styles applied to elements

It’s simple and intuitive *👍.*

New theme

But let’s say we need to add support for a dark theme for the current style scheme due to business requirements. *How do we implement it? *🧐

Experienced developers 🤓 will tell you that you should use mapping to substitute the correct value into the selector from each theme. In this way, we will provide extensibility for new themes.

Let’s change our simple variable list to a color theme map

    $themes: (
     "default": (
       primary: #d75894,
       secondary: #9b3dca,
       background: #fafafa,
     ),
     "dark": (
       primary: #5e84ff,
       secondary: #0dd0ff,
       background: #1b1918,
     )
    );
Enter fullscreen mode Exit fullscreen mode

Themes applying

    @use "variables";
    @use "sass:map";


    @mixin setTheme($theme-map) {
     background: map.get($theme-map, "background");


     h1 {
       color: map.get($theme-map, "primary")
     }


     p {
       color: map.get($theme-map, "secondary")
     }
    }


    body {
     @each $theme-key in map.keys(variables.$themes) {
       &[data-theme="#{$theme-key}"]{
           @include setTheme(map.get(variables.$themes, $theme-key))
       }
     }
    }
Enter fullscreen mode Exit fullscreen mode

Result

Applied the new dark theme

Yay, we’ve achieved the requested behavior. But at what cost?

Problems

As you can see from this small example, the amount of code to support the new dark theme has increased, and the old scheme had to be refactored.

Another disadvantage is obtained is the increase in the resulting CSS file due to having multiple themes simultaneously.

And hence its size, which takes time 📉 to download and parse.

    body[data-theme=default] {
     background: #fafafa;
    }
    body[data-theme=default] h1 {
     color: #d75894;
    }
    body[data-theme=default] p {
     color: #9b3dca;
    }
    body[data-theme=dark] {
     background: #1b1918;
    }
    body[data-theme=dark] h1 {
     color: #5e84ff;
    }
    body[data-theme=dark] p {
     color: #0dd0ff;
    }
Enter fullscreen mode Exit fullscreen mode

As a consequence, with the growth of the code base and the requirement for stylization, we will get:

  • Increasing complexity of style architecture in the development of individual components

  • Maintenance and development of new features will be harder every time

  • Constant refactoring and need for regression screen tests

These problems will undoubtedly affect the speed of development, the quality of the result, and the convenience of developers.

Unfortunately, many libraries developed using SCSS, such as @angular/material, encourage this approach. Many developers are unaware of the recommended ways of styling via mixins, which leads to anti-pattern styling as well as the use of ::ng-deep

Those who have ever upgraded Angular in conjunction with @angular/material will understand UI problems in regression tests after upgrade if you don’t use the recommended way of component customization

So what’s the solution to this problem? read more...

Top comments (3)

Collapse
 
fyodorio profile image
Fyodor

So what’s the solution to this problem? read more...

That's not fair 😄

Collapse
 
jangelodev profile image
João Angelo

Maksim Dolgih,
Great article, very useful!
Thanks for sharing...

Collapse
 
best_codes profile image
Best Codes

Great post! There are a couple issues in your markdown, especially around the italics and stuff…