CSS Variables: Access Custom Properties with JavaScript

Warning This article was written over six months ago, and may contain outdated information.

The recent release of Firefox 31 brought an implementation of CSS Variables. Based on that, Daniel Imms wrote an interesting post, What CSS Variables Can Do That Preprocessors Can’t, where he investigates a few use cases for native variables over those provided by pre-processors like Sass and LESS (there’s a common argument that CSS variables are unnecesary as we already have them, and more flexibly, in pre-processors).

In this article I’m going to expand on Daniel’s article a little, showing an advantage of CSS Variables that he doesn’t talk about in detail: interacting with them using JavaScript.

Before going ahead, a quick refresher / introduction to CSS Variables. What’s been defined so far is Custom Properties, which allow you to define a new property, scope it to part of the document, and assign a value to it. For example, the following code defines a custom property called –foo-bar, scoped to the body element, with a colour value:

body { --foo-bar: #f00; }

The property can now be called later in the stylesheet, and its value will be used as the value of the property its applied to; the result of this code is that the div has a background-color of #f00:

div { background-color: var(--foo-bar); }

So, back to Daniel’s article. In it he points out two key advantages of native over pre-processors:

[They] can change at runtime, allowing the implementation of things like theming to be done more elegantly. They’re also scoped, enabling a variable to be changed on only a subset of the DOM tree.

In his examples he looks mostly at the utility of scoping, but the point about being able to change at runtime is equally important. Earlier versions of the spec defined an API interface which allowed you to get and set custom properties; this has since been pulled while a new API is developed. In the meantime, however, you can still use the CSSStyleDeclaration interface to interact with custom properties.

To return to our previously defined variable –foo-bar, you could get the value of this through JS by using the getComputedStyle() and getPropertyValue() methods, like so (suggested by Cameron McCormack):

var bodyStyles = window.getComputedStyle(document.body);
var fooBar = bodyStyles.getPropertyValue('--foo-bar');

But more interestingly, you can set the value through the setProperty() method on the style object:

body.style.setProperty('--foo-bar', newValue);

As a very simple example, here’s a quick demo showing how you could update a range of properties with a shared colour value — useful, perhaps, for showing a live preview of a theme change:

[DEMO] Colour change with custom properties (Firefox 31+ required)

Of course, this is possible without CSS Variables — but it’s easier with them: there’s only one value to update and no changes to the DOM. I think interaction with JS through an API is a great feature, but sadly, CSS Variables face an uncertain future — they’ve been pulled from Chrome, and are only listed as ‘Under Consideration’ in IE.

Thanks to Neil McCallion for code aid.

4 comments on
“CSS Variables: Access Custom Properties with JavaScript”

  1. As someone who uses SVG a lot, I’ve really been waiting for CSS variables to be adopted. They allow you to create reusable SVG icons that can be customized indefinitely through CSS.

    CSS variables would be similarly useful for HTML widgets or other reusable code. The widget author would define customizable styles using variables (with appropriate fallbacks). The page author could then define the variables for the widget container, without having to worry about the actual CSS classes or other selectors used in the widget — and without having to worry about selector clashes between different parts of the page.

    Amelia Bellamy-Royds [September 1st, 2014, 19:48]

  2. Careful with those words : “sadly, CSS Variables face an uncertain future — they’ve been pulled from Chrome […]”

    -> see Tab Atkins Jr. on 2014/02/11 :

    “To make it clearer to those watching at home, our current Variables
    impl is pretty hacky, and kinda intrusive and slow (of the “everything
    slows down when you use it” variety). We know roughly how to
    implement it faster, but doing it right depends on some other rewrites
    we intend on doing, so we’ll re-add this later when they’re done.

    This is definitely not a judgement on the feature itself. ”

    Source : https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/ScKw9zYRkBc

  3. It would be a pity if CSS variables don’t get implemented by most browsers. It’s not that you can’t do without them — we all do, via JavaScript. But it leads to great inefficiencies, like injecting style attributes all over the place. Thanks for an informative article.

  4. Paul: It’s great that Tab is confident they’ll be reimplemented, but until I see them back in Chrome, with IE & Safari following, I continue to think the future of CSS Variables is uncertain.