Home / CSS3 / Using of CSS variable with Sass Mixins, Complete Guide

Using of CSS variable with Sass Mixins, Complete Guide

Tuesday July 20, 2021
6 minutes read
149 Views
sass mixins

CSS variables and Sass mixins are powerful tools in and of themselves. With a little imagination, we can encourage them to collaborate on more flexible and reliable solutions.

The designer with whom I worked had used the same color but with varied opacities on several occasions. Many of his components were made up of different hues of the same color.

Declaring all color variants as separate variables is a common and time-consuming implementation. Normally, we’d wind up with something like this:

/* Color palette */
:root {
	--color-primary: #16498a;
	--color-primary-a90: rgba(22, 73, 138, 0.9);
	--color-primary-a80: rgba(22, 73, 138, 0.8);
	--color-primary-a70: rgba(22, 73, 138, 0.7);
	--color-primary-a60: rgba(22, 73, 138, 0.6);
	--color-primary-a50: rgba(22, 73, 138, 0.5);
	--color-primary-a40: rgba(22, 73, 138, 0.4);
	--color-primary-a30: rgba(22, 73, 138, 0.3);
	--color-primary-a20: rgba(22, 73, 138, 0.2);
	--color-primary-a10: rgba(22, 73, 138, 0.1);

	--color-secondary: #12284c;
	--color-secondary-a90: rgba(18, 40, 76, 0.9);

	--color-tertiary: #27add5;
	--color-black: #000;
	--color-gray: #ececec;
	--color-light-gray: #f9f9f9;
	--color-danger: #d63939;
	--color-success: #4fc0b0;
	--color-white: #fff;
}

Because of the dynamic nature of CSS Variables, I prefer them to traditional SASS variables. They also make it easier for me to write clean, clear, and modular code by eliminating the need to import sass color maps every time I wish to refer to a variable.

In a normal style guide, there are approximately 9 different colors and their variations. Our previous strategy had a number of flaws. It resulted in enormous CSS files and made even the tiniest modification to our primary or secondary colors a major headache.

So how can we solve these problems?

The best solution would enable us to:

  • Maintain a single point of reference for all of my colour definitions. In my instance, this indicates that I should only have 9 colour variables.
  • Without adding complication, use any opacity variety of any of the brand colours.
  • Change the colour of any brand with just one line of code.
  • Use dynamic CSS Variables to their full potential.

Sass’s rgba mixin

I started with Sass’s RGBA mixin. It seemed like a straightforward answer.

border-top: rgba(#16498a, .4); // works.

border-top: rgba(22, 73, 138, 0.4); // works.

border-top: rgba(var(--color-primary), 0.4); // does not work.

Sass’ RGBA kung-fu The RGBA function in Sass accepts four parameters separated by commas. It allows two parameters if we wish to use hex values. Under the hood, Sass uses RGB/HSL functions to transform hex colour values to RGB or HSL. Here are the CSS versions of the three examples above:

// border-top: rgba(#16498a, .4); compiles to:
border-top: rgba(22, 73, 138, 0.4);

//border-top: (22, 73, 138, 0.4); compiles to:
border-top: (22, 73, 138, 0.4);

//border-top: rgba(var(--color-primary), 0.4); compiles to:
border-top: rgba(var(--color-primary), 0.4);

The example in which a CSS variable was utilized did not work. The outcome is incorrect when using SASS’s rgba function with CSS variables.

According to the official CSS spec, “when replacing var() references in a property’s value, the values of custom properties are substituted as is.”

On the other hand, these values are only interpreted at the time of execution. When SASS was compiled to CSS, var(–color-primary) was not understood as a color value. Instead, the SASS rgba function failed to build properly because the compiler observed a random string.

Furthermore, the string can be anything as long as it is grammatically valid.

// For example, this is valid.
--foo: if(x > 5) this.width = 10; 
// This code is obviously useless as a CSS variable. But can be used by javascript at run time.

As a result, var(– color-primary) isn’t a colour value at compile time, thus it fails to compile. Fortunately for me, it gracefully falls back to the normal rgba function.

/* Sass will fail to compile this line of code. But it fails gracefully and outputs the exact same line of code.
Now, when the browser interprets this code, it will try to use the native rgba function.
*/
Border-top: rgba(var(--color-primary), 0.4);

The native rgba function

The native rgba function only accepts 4 comma-separated values as parameters, thus we can’t utilize hex color values, according to the spec. Perhaps we might start by declaring our variables as comma-separated RGB values.

:root {
  --color-primary: 22, 73, 138;
}

div {
  border-top: 1px solid rgba(var(--color-primary), 0.4) ;
}

His new strategy was successful! We can now simply employ opacity versions of any color.

However, two new issues occurred as a result of this method:

  • A value like ’22, 73, 138′ is difficult to read; using this method would need to convert all of my color values to this format.
  • We can no longer use a colour picker to experiment with these values. These values are not recognized as colors by my IDE or the Chrome dev tools.

This method takes a long time and isn’t very expressive. However, we are moving closer to a more environmentally friendly alternative.

The solution

We’d like to be able to use CSS variables instead of having to declare ten different opacity versions for each color. I believe I must use comma-separated RGB values, but I also require expressive and easy-to-edit code.

:root {
  --color-primary: #16498a;
  --color-primary-rgb: 22, 73, 138;
}

h1 {
  color: var(--color-primary);
}

h2 {
  color: rgba(var(--color-primary-rgb), 0.4);
}

We compromised on simplicity to make our approach work by declaring two copies of the same color, one HEX, and one RGB. This method increases the number of variables compared to what I wanted, but it’s a good tradeoff.

So far, we’ve managed to produce multiple hues of our colors using CSS variables. There is, however, still potential for development. There are two concerns with it:

  • We still have to manually convert all of our colors from hex to RGB.
  • Every time we want to modify one of our colors, we have to edit numerous variables.

This function transforms hex color values to RGB values. The function takes any color and extracts the red, green, and blue levels then return them in a comma-separated format.

@function hexToRGB($hex) {
  @return red($hex), green($hex), blue($hex);
}
:root {
    --color-primary: #16498a;
    --color-primary-rgb: #{hexToRGB(#16498a)};
}

We won’t have to make colour conversions manually anymore thanks to this feature.

The solution is currently extremely close to meeting our goals. For each of my variables, we still want to construct a single source of truth.

@function hexToRGB($hex) {
  @return red($hex), green($hex), blue($hex);
}

$color-primary: #16498a;

:root {
    --color-primary: #{$color-primary};
    --color-primary--rgb: #{hexToRGB($color-primary)};
}

Conclusion

The features of Sass include functions, mixins, variables, and native CSS variables. None of these, however, is a full answer in and of itself. To come up with solid solutions, they must collaborate.

I started off trying to figure out how to use CSS variables, or custom properties, with Sass functions and mixins. I was able to come up with a good solution after some compromise and much testing, which I hope you will find useful.

Read More


Post author

A bright, talented, ambitious and self-motivated 💻 Freelancer, ⌨ Programmer, JavaScript and Typescript lover 📍

  Tweet It


Leave a Reply

Your email address will not be published. Required fields are marked *