· 5 min read

CSS Variables vs. SASS Variables

This article was auto-translated from Chinese. Some nuances may be lost in translation.

Previously, I wrote a post about my thoughts on CSS variables. Initially, I didn’t have high expectations for this feature—being used to SASS variables, CSS variables felt like a clumsy system in comparison. But if you feel the same way, you might want to check out this article: Why should you care Css variables.

CSS variables have been around for a while now, and browser support isn’t too bad. You might have thought that almost everything CSS variables can do can already be done in SASS, and when combined with SASS functions and data types (lists, maps), variables become even more flexible and powerful.

However, what I want to share here is where CSS variables truly shine.

This article assumes that you already have some basic understanding of CSS variables.

As a side note, this post does not provide an exhaustive guide on how to use CSS variables. Any suggestions or feedback are welcome, and I’ll find time later to write a more comprehensive post.

Browser Support

BrowserVersion
Chrome49
Firefox42
Safari9.1

Custom Property

Only when you make it behave like a property does it become more powerful than traditional preprocessors.

The first thing to clarify is that in the CSS specification, variables are actually called custom properties. What does that mean? Variables vs. properties—it gets confusing!

Don’t worry. It simply means that when using CSS variables, we should think of them as regular CSS properties rather than just standard variables. Below, I’ll introduce some ways to use CSS variables.

Why You Should Use CSS Variables

  • You don’t need a preprocessor to use these properties.
  • You can establish hierarchies using initial and inherit.
  • Browsers will re-render when needed.
  • You can access and manipulate them with JavaScript (more on this later).

Property Characteristics

Since it is a CSS property, it naturally shares several characteristics:

  • Values like initial and inherit are available.
  • They are accessed via var(--variable-name).
  • They can be used inside inline-styles.
  • They can be read and set using JavaScript.

Among these, the biggest highlights are their usability in inline styles and the ability to read and set them with JS. This is the biggest difference compared to preprocessors like SASS and LESS, and it opens up new possibilities for CSS. Let’s look at some examples!

:root {
  --mainColor: #abc;
  --subColor: #ccc;
}

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

Here, the custom properties declared in :root will be inherited by all elements. That is the nature of a custom property.

inline-style

Because it is a property, you can naturally write it like this:

<h1 style="color: var(--mainColor);">
  Hello, world
</h1>

This might not seem like a big deal at first glance, since the same outcome can be achieved with classes and SCSS variables, but it brings brand-new possibilities when writing inline styles.

React Inline Styles

For example, in React, we might need to write some inline styles. However, managing colors outside of SCSS often feels awkward. You either hardcode the color hex codes and roll up your sleeves to change them one by one later, maintain a separate color variable map in JS, or assign a class name for every single color variable (perhaps the best conventional approach).

Now, with CSS variables, it becomes very convenient:

const styles = {
  heading: {
    fontSize: "14px",
    color: "var(--mainColor)",
  },
  warn: {
    color: "var(--warnColor)",
  },
}

const heading = ({ title }) => <h1 style={styles.heading}>{title}</h1>

This article only focuses on introducing CSS variables; in fact, there are other great ways to manage styles in React.

Grid

When configuring gutters, we can now achieve this using CSS variables. In other words, we can set variable values using @media queries—something traditional preprocessors cannot do.

JavaScript Control

Through JavaScript, we can easily read or set CSS variable values, achieving a separation between view and JS. For instance, when we have some values calculated in JS that need to be passed to CSS, traditionally, we might compute the value in JS and then apply it via an inline style.

However, this can lead to a few issues:

  • The value might not be directly usable, or CSS might want to perform further operations on it. This requires modifying the JavaScript code, which is cumbersome.
  • Because the value is applied via inline styles, CSS has very little control over it.

With CSS variables, reading and writing values is a breeze.

Reading a Value
HTMLElement.style.getPropertyValue("--mainColor")
Setting a Value
HTMLElement.style.setProperty("--mainColor", "#abc")

Therefore, we can easily attach event listeners to inject values of interest directly into our variables:

const element = document.addEventListener("mousedown", e => {
  // some HTMLElement;
  element.style.setProperty("--pageX", e.pageX)
  element.style.setProperty("--pageY", e.pageY)
})
Feature Detection

If you want to check whether the current browser supports CSS variables, you can use the CSS.supports API:

CSS.supports('(--css: variables)') CSS.supports('not (--css: variables)')

Future Challenges

As there are more and more ways to manage variables—including setting them through JavaScript—we should be more disciplined when controlling them:

  • Centralize variable declarations: Keep global variables organized in a single file or directory for easier maintenance later. The same applies when declaring CSS variables.
  • If a variable is meant to be updated via JS, consider prefixing it as a marker, such as --js-pageX, etc.

Conclusion

This article introduced the usage and scenarios for CSS variables. Previously, I also thought CSS variables were awkward—not only looking ugly in syntax, but also lacking built-in manipulation functions.

However, once you understand the concept that CSS variables are actually custom properties, you will discover possibilities that CSS previously could never achieve. There is no need to choose between SASS and CSS variables; we can even use both in tandem to create powerful effects that were once out of reach.

Related Posts

Explore Other Topics