Thanks to Molly Holzschlag’s tweet yesterday, I learned there was an Editor’s Draft of CSS Variables.
Let me first say that I think it’s awesome that the W3C is taking this on. I think that variables in CSS will ultimately be a good thing. It will make it easy to reuse colors and other CSS properties. It will make large amounts of redundancy go away. It will make CSS files smaller, and therefore give less toe-holds to bugs.
That being said I have a major complaint with the implementation–in a word “data.”
See, here is how CSS variables are supposed to work according to the draft.
I create a property in the root named “data-header-color.”
Then to refer to that color elsewhere, I use a construct that looks like a function named “data()” to retrieve it as so:
As far as I can tell, the only explanation in the draft for why this is, is that it is trying to match the HTML specification for “data”:
The naming here is loosely based on the form of custom data attributes in HTML5. However, as defined here, the syntax for variable usage is different from the syntax for variable definition (i.e. data-foo for definition, data(foo) for usage). Some have suggested that the syntaxes should should match, using functional syntax in both cases. Others have suggested using a prefixed symbol instead of functional syntax (e.g. $foo) for both the property and usage.
Well at least they are aware that some might object to this format. So let me add my voice. I object. Variables are a pretty standard construct, people know how they work. Make them work like variables in other languages. I have a bunch of reasons here:
- Two different syntaxes for creation and consumption seems confusing
- It looks like you’re calling a function, but you’re not. You’re referring to a variable. That’s confusing.
- CSS and HTML don’t have a lot of overlap in syntax, why is adding some a good thing?
My preference here is that I can just use plain old words as a variable, then consume them as plain old words. That being said I would be okay with a prefixed symbol, like a $ if it comes down to some sort of parsing issue.
That’s my major problem with the draft, but I have one other issue with the behavior on invalid variables. Like if you set the margin to #FFFFFF. Basically if you have this code:
Then the p comes out as red, but if you have this code:
The p comes out transparent.
This sort of change in behavior might be pretty confusing. The explanation makes some sense:
The invalid at computed-value time concept exists because variables can’t “fail early” like other syntax errors can, so by the time the user agent realizes a property value is invalid, it’s already thrown away the other cascaded values. I think “attr()” needs to rely on it as well, as its behavior is almost identical to variables.
But I imagine this is something that browser manufacturers can handle as they control the behavior of “throw[ing] away the other cascaded values.” They could hold on to cascaded values until they are done computing variables. But maybe I’m missing something here. But it’s also worth considering if this will make invalid CSS easier to track down. I doubt it, but until a browser implements these, it will be hard to determine if that is true.
Anyway. The good news here is that this is the editor’s draft, not the recommendation. This means that now is the time to start analyzing this spec and commenting on it. So what do you think?
5 thoughts on “CSS Variables Draft”
Totally agree with you on both points
I agree with you 100% here. One of the other reasons for the single variable method is that it makes the variables stand out more when scanning stylesheets.
data-my-background is easier to miss than @my-background or $my-background. Just scan through a CSS file and see how easy it is to quickly identify hex color values.
The simplest solution would be to copy/incorporate LESS or Sass?
Implementation is above my pay grade, but my guess is that the “hold onto cascaded values” idea would likely open up buffer overflow exploits.
Agree on both counts.