Why CSS Needs No Variables
Published on AprĀ 1, 2009 (updated FebĀ 5, 2024), filed under development, css (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
Iām Jens (long: Jens Oliver Meiert), and Iām a web developer, manager, and author. Iāve been working as a technical lead and engineering manager for companies youāve never heard of and companies you use every day, 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.)