Using SCSS Variables with CSS Functions

CSS is essential in developing website aesthetics but clunky compared to many modern programming languages. Fortunately, SCSS was developed to help reduce this burden and with a few simple syntactic steps, one can even use them with native CSS functions!
scss css calc variables

The Cascading Style Sheets (CSS) specification has been essential to website aesthetics since the mid-1990s. It’s not quite a programming language and has historically lacked most modern development tools such as functions or variables. Fortunately, SCSS provides an extension to CSS syntax that allows for such programming.

SCSS allows developers to define a variable that gets replaced at compile-time much like how #define directives work in languages like C. When the SCSS files are compiled down to CSS each instance of a variable is replaced with its value. This makes the life of web developers easier but can cause some headaches when mixing with some native CSS features like functions.

TL;DR – use the #{} syntax as such: calc(100vh - #{$variable});

SCSS Variables & CSS Functions

An issue can arise when using such variables in SCSS with calc, transform, scale, or any number of the available CSS built-in functions. CSS functions expect a certain syntax and the $-adorned SCSS is not within spec. Below is an example of an attempt at using an SCSS variable with the CSS calc function that one might make without being aware of the issue:

// Define a variable
$header_height: 90px;

// Attempt to use it in the CSS calc function
// NOTE: Does Not Work!!!
.overlay{
  height: calc(100vh - $header_height);
}

The error message here will vary depending on how one chooses to compile their SCSS. It might be a compile-time error or simply a Unexpected term nag via one’s linter. In any case, the issue arises from inserting the $header_height variable directly into the CSS function.

SCSS is an extension of CSS meaning any valid CSS is also valid CSS but not all SCSS is valid CSS and such variable definition is an illustration of just that.

Immediately, this seems like a major issue. Fortunately, the work-around is simple and should feel native to any web programmer familiar with syntaxes used by React/JSX or similar tools. Below is how to insert an SCSS variable into the CSS calc function:

// Define the variable the same way
$header_height: 90px;

// Use the #{} syntax to insert a variable
// into the calc function correctly.
.overlay{
  height: calc(100vh - #{$header_height});
}

This code compiles without error and will return a value of 100vh - 90px to the height parameter of the .overlay class. CSS now allows programmers to use variables (a.k.a. custom properties) in a similar fashion. Consider the above code rewritten in pure CSS:

/** Defines a class to hold custom properties **/
.custom{

  /** Defines the Height **/
  --height: 90px;
}

.overlay{

  /** Uses var() function to access custom property **/
  height: calc(100vh - var(--height));
}

The end result in this short contrived example is the same as the previous code. The SCSS syntax is arguably sassier (living up to the directive’s name) but does lose some of the advantages of CSS custom properties. Namely, JavaScript code is not able to directly access and manipulate them since they are replaced with their static values at compile time. Additionally, CSS custom properties cascade and provide systems of inheritance.

Knowing the Difference: CSS/SASS/SCSS

Cascading Styles Sheets (CSS) is the language in which websites express their aesthetics, structure, and often much of their functionality. Syntactically Awesome Style Sheets (SASS) is a preprocessor directive by which more dynamic CSS can be written. Sassy CSS (SCSS) is the syntax in which this language is written.

SASS files are written with the extension .sass and pre-date the SCSS files with the extension .scss. The difference is in syntax — SCSS is an extension of CSS such that all CSS is valid SCSS whereas SASS has an indentation-formatted styling that, among other things, avoids the need for brackets. They both compile to CSS under the hood and the difference is mostly syntactic.

Final Thoughts

SCSS is utilized by most modern web frameworks that are CSS heavy like Boostrap. It greatly reduces the amount of code needed to produce comprehensive classes of style definitions for any size web project. SCSS works in complement with modern tools like webpack and typescript to help reduce the complexity of many web project code bases.

The use of SCSS variables certainly makes like easy in many cases. A little syntactic know-how can help make use of both SCSS variables and CSS functions. However, it would be a shame to write off CSS custom properties entirely given their unique ability to be directly accessed, manipulated, and inherited within the browser after compile time.

Zαck West
Full-Stack Software Engineer with 10+ years of experience. Expertise in developing distributed systems, implementing object-oriented models with a focus on semantic clarity, driving development with TDD, enhancing interfaces through thoughtful visual design, and developing deep learning agents.