Thomas Gossmann

Unicyclist. Artist. Developer.

On CSS Variables

Since Firefox supports CSS variables in their nightly build (version 29), I recently tested CSS variables (View on dabblet). While the spec has changed over one and a half year ago to use the var-* syntax, Atkins Jr (spec author) also explains why.

My first reaction when I first read about this, was the same along others that used preprocessors before: „WTF? Why not simply $var“ ?!? I recommend you to read the explanation from Tab Atkins I linked above, which should cool down your first anger.

Getting the scope

To understand CSS variables it’s about getting the scope in which they run. Variables used in preprocessors use the lexical scope, the same as we are used to in regular programming languages. CSS variables instead are using a dynamic scope. I would like to call it cascading scope here, as CSS variables have access to the cascade and as such, those selectors with the highest specifity will win the race on the final value. That’s something preprocessors don’t have access to, so its worth thinking in this direction.


Variables are not the correct term describing this behavior in my eyes. The spec author(s) are calling them custom-properties. I think both terms are misleading and wrong. As Glazman wrotes on CSS variables, declarations consist of the following pattern: „<property> : <value>„. Properties are on the left side of the colon, but custom properties go on the right side? I think you can guess on which side custom-values will go one day? No. The term properties is definitely wrong here. Better would be custom-values or since they are dynamic, call them dynamic-values. My favorite is cascading-values since this is their origin for their dynamic behavior.

My Ideas

  • Rename CSS variables to what they actually are: cascading-values or dynamic-values or sth else.
  • Instead of var-* and var() use val-* and val().

As far as I read variables are still to come to be used in mixins. These variables would be lexically scoped then. This would require a spec for lexically scoped variables. I think this spec can be used globally and not only locally within mixins. And I think both lexically scoped variables and dynamically scoped values can live side-by-side depending on what you want and need to use.