Jens Oliver Meiert

Why CSS Needs No Variables

Published on Apr 1, 2009 (updated Feb 5, 2024), filed under (feed). (Share this on Mastodon or Bluesky?)

This and many other posts are also available as a pretty, well-behaved ebook: On Web Development.

This post is partially outdated.

(No, this is not an April Fools’ joke.)

CSS variables and constants are one of the top features web developers are asking for in web development fora, magazines, blogs, and on W3C’s www-style. Following a concept written by Daniel Glazman and Apple’s Dave Hyatt, the WebKit rendering engine even temporarily included support for variables. And in the meantime, others went for pragmatic solutions and used PHP to make variables work (by that suggesting that variables might not be needed in CSS).

Listening to web developer demands is a good thing. Yet there’s something odd about CSS variables, and a few CSS connoisseurs like Bert Bos shared some of their concerns in public. I’m not convinced about CSS variables, either, yet my objections are based on an emphasis on CSS coding style, including the idea of “using every declaration just once” which I explained under the hood of performance considerations: Declaration-based sorting cannot just reduce file size, it can also make style sheets more maintainable, to the extent that there is no need for variables, either.

Comparing CSS Variables and Declaration-Based Sorting

Before I illustrate my case against CSS variables from this coding style perspective please note that I’m not going for a detailed case study that compares a number of different styles. Instead I have to ask to accept the aforementioned style; I’ll use it as a reference until I get to write more about all of this.

I’ll now use a simplified style sheet, apply both Daniel’s and Dave’s variables suggestion as well as the “every declaration just once” method, and comment. The file size data are merely added for the impression of completeness.

#selector1 { color: black; }
#selector2 { color: black; }
#selector3 { color: black; }
#selector4 { background: black; }
#selector5 { background: black; }
#selector6 { background: black; }

The above is a sample style sheet (188 bytes) that ignores other things in a typical style sheet but features recurring property values that make variables so attractive.

Using CSS variables alters that sample to the following:

@variables { elementcolor: black; }
#selector1 { color: var(elementcolor); }
#selector2 { color: var(elementcolor); }
#selector3 { color: var(elementcolor); }
#selector4 { background: var(elementcolor); }
#selector5 { background: var(elementcolor); }
#selector6 { background: var(elementcolor); }

This style sheet weighs 296 bytes (108 bytes or about 57% bigger than the original) but, imagining a huge, complex style sheet, one might find it a bit easier to maintain.

In comparison, using every declaration just once, which should mean nearly the same maintenance implications as variables, gives us:

#selector1, #selector2, #selector3 { color: black; }
#selector4, #selector5, #selector6 { background: black; }

This freshly sorted style sheet weighs 110 bytes (78 bytes smaller than the original).

I said that I’d just go for applying two techniques (variables and declaration sorting), but let’s see how combining both approaches would look like:

@variables { elementcolor: black; }
#selector1, #selector2, #selector3 { color: var(elementcolor); }
#selector4, #selector5, #selector6 { background: var(elementcolor); }

This combined version is 170 bytes big (18 bytes smaller than the original sample).

Early Final Words

I know this day would be so much sunnier if I’d do more than just throwing code styles and numbers around, yet there’s a point in this. The main point is to see declaration-based sorting as a method not only to reduce file size and improve performance (as I presented it originally), but to use selector grouping to make style sheets more maintainable without needing to resort to variables.

Handing over to Bert again:

For many people, style sheets with constants will thus simply not be usable. It is too difficult to look in two places at once, the place where a value is used and the place where it is defined, if you don’t know why the rule is split in this way. Many people are confused by indirection anyway and adding an extra one, in addition to the element and class names, has the same effect as obfuscating the style sheet.

The next time we talk about variables we’ll hopefully discuss CSS Selector Variables instead. If I ever manage to follow up on those.

About Me

Jens Oliver Meiert, on November 9, 2024.

I’m Jens (long: Jens Oliver Meiert), and I’m a web developer, manager, and author. I’ve worked as a technical lead and engineering manager for small and large enterprises, I’m an occasional contributor to web standards (like HTML, CSS, WCAG), and I write and review books for O’Reilly and Frontend Dogma.

I love trying things, not only in web development and engineering management, but also in other areas like philosophy. Here on meiert.com I share some of my experiences and views. (I value you being critical, interpreting charitably, and giving feedback.)