Thinking

Pros and cons of CSS variables.

For years CSS has had a major problem regarding sustainable development. The larger websites grew, the harder it became to maintain their styles. Simple changes to colours, fonts and spacing could take much longer than anticipated as finding and replacing the right values was a manual task.

Then came the rise of CSS preprocessors like Sass and Less, bringing a whole new programmatic approach to the development of a project’s styles. Amongst many other features, values could now be stored as reusable variables, placed as needed, and manipulated in-situ. Entire visual systems could be reliably and logically tweaked from a single variable change.

However, these new feature packed languages couldn’t run in a browser and were required to be compiled back down into static, rigid CSS before deploying into a project. CSS itself needed to evolve to step into the modern era of dynamic and modular development.

Enter CSS variables. This new feature launched in July 2014 with Firefox 31 and very slowly gathered momentum launching into other popular browsers over the following few years.

Phone on desk displaying code

Photo by Caspar Camille Rubin

Basic usage

At their core, CSS variables simply offer a means to manage property values from a single point. This enables quick and simple control of styles across multiple elements.

:root {
  --variable-name: 'This value can be updated here';
}

section:before {
  content: var(--variable-name); /* This property will take the current variable value */
}

Advanced tricks

This is just the tip of the iceberg when it comes to leveraging the dynamic power of CSS variables.

Variables can be overwritten and updated for specific conditions and can be used within runtime calculations accessing information about the current layout that preprocessors could never reach.

Here a value is dynamically calculated by the current variable values:

:root {
  --block-width: 100px;
  --gutter-size: 10px;
}

section {
  width: calc(var(--block-width) - (var(--gutter-size) * 2));
}

Using the ability to overwrite values, utility classes can provide style tweaks without writing brand new styles:

section.big-gutter {
  --gutter-size: 30px;
}

Media queries can overwrite variable values to quickly provide style tweaks based on the screen size. With the following, the block width used by the example above is set to 300px when the screen is large enough:

@media (min-width: 500px) {
  :root {
    --block-width: 300px;
  }
}

The pros

Cleaner stylesheets

One of the major benefits of CSS variables is that it allows developers to consolidate their common properties into easy to reach locations, making code more readable and easier to maintain. Whilst this is a possibility in preprocessors, leveraging the technology in the browser itself gives access to more runtime information.

This opens up the ability for developers to work closer with designers to create a flexible base for design systems allowing them to focus on real work instead of balancing plates.

Easier theming

One of the all-round favourite aspects of this technology is the ability to theme and skin components or entire pages with some planning and just a few lines of additional CSS.

Take a look at the example below to see how variable overwrites can be used to swap styles in a flash:

Read and write pivotal style properties with JS

With more and more frontend development taking the form of Javascript dominant frameworks and integrations, the need to seamlessly communicate between form and function is more critical than ever. Thankfully the values of CSS variables are easily read and written by Javascript adding even more levels of runtime flexibility to an already versatile feature.

Check out the example below to see Javascript and CSS working together with minimal effort:

… And cons

Predictability at the cost of flexibility

A minor downside when using CSS variables is the possibility of building yourself a variable system that doesn’t give the flexibility you might have required in the long run. Simply creating one variable for every unique value doesn’t offer the long term flexibility you might need.

This can be overcome with a little planning and some understanding of the context of each component you’re developing. Dynamic design systems need to be written with sustainability and versatility in mind, instead of focusing on the convenience variables bring.

Limited by CSS itself

Regardless of the flexibility this technology brings, CSS variables are still part of a very rigid ecosystem. The biggest limiting factor is CSS itself.

Whilst things like calc can handle most dynamic property values using variables, this isn’t always the case. You may think that the ability to set a colour variable would be the end of the story but this breaks down as soon as the need to adjust opacity crops up.

CSS preprocessors still hold the trump card on this issue as they can take colours and update alpha values with ease. Amongst many other benefits these preprocessors bring, it’s likely these two systems will need to continue to work together as browsers improve their technology.

What’s stopping you?

Given the power of this technology and the ability to integrate CSS variables into existing development, you may be asking yourself what’s the catch.

Unfortunately if your project is one of the many that still require Internet Explorer support you’re out of luck. There is zero support for CSS variables in any version of Internet Explorer and, whilst Microsoft has redeemed themselves with their Edge browser, some project demographics could still see a requirement to support the relic browsers. However, CSS preprocessors can still provide some of the benefits mentioned above if you’re looking for cleaner stylesheets.

If Internet Explorer is off the table for you then why not give CSS variables a go? We absolutely love the technology and if you’re unsure of where to go from here get in touch, we’d love to help you build the project you need with the tools that are right for you.

This website uses cookies

This website uses cookies to improve your experience. By using PRISM⁵⁵, you accept our use of cookies.