Friday, April 25th, 2008

CSS Variables are next?

Category: Browsers, CSS, WebKit

<p>How long have you wanted to name colors and such in your CSS instead of having to use search and replace (which breaks if you share the same colors ;) ?

We have a proposal thanks to Daniel Glazman and the ubiquitous David Hyatt.

Since the release of CSS Level 2 Recommendation ten years ago in may 1998, the Web authors’ community has been requesting a way of defining variables in CSS. Variables allow to define stylesheet-wide values identified by a token and usable in all CSS declarations. If a value is often used in a stylesheet – a common example is the value of the color or background-color properties – it’s then easy to update the whole stylesheet statically or dynamically modifying just one variable instead of modifying all style rules applying the property/value pair. We expect CSS Variables to receive a very positive feedback from both the Web authors’ community and browser vendors.

With Dave on the author list, we can expect the following to work on WebKit sometime soon!

  1. @variables {
  2.   CorporateLogoBGColor: #fe8d12;
  3. }
  4.  
  5. div.logoContainer {
  6.   background-color: var(CorporateLogoBGColor);
  7. }

(via Dylan Schiemann)

Related Content:

Posted by Dion Almaer at 8:49 am
27 Comments

++++-
4.6 rating from 46 votes

27 Comments »

Comments feed TrackBack URI

Very useful, I always wanted this.

What will happen if their are two CSS files included in the page, and the variable is defined in one and used in other. What if Javascript is used to add CSS to the page after it finishes loading?

Comment by nileshbansal — April 25, 2008

I still cannot believe that this was not part of css v0.5 and that we’ve had to wait until 2008 for another proposal. I hope this will become the standard a.s.a.p. so that the great javascript frameworks can start doing the ‘hard’ work for the browser builders

Comment by SchizoDuckie — April 25, 2008

CSS variables are a good thing. However, the need for variables can often be reduced by factoring your CSS declarations by descriptor instead of selector. In other words, instead of

.style1 { color: red; font-family: sans-serif; }
.style2 { color: red; font-family: serif; }
.style3 { color: blue; font-family: sans-serif; }

try

.style1, .style2 { color: red; }
.style1, .style3 { font-family: sans-serif; }

This pattern also often does a better job of separating various aspects of representation.

Comment by tora — April 25, 2008

Is the reason it is called “variables” in one place and “var” in the other place to save a couple of bytes? The first is included only once in a file and the other potentially multiple times. Is this a good enough reason?

In the meantime, for at least the static case, this method provides documentation and search/replace support:

div.logoContainer {
background-color: #fe8d12; /* CorporateLogoBGColor */
}

Changing the value would necessitate changing others named (commented) the same. Not having seen something like this, for example in Dojo style sheets, has been very disappointing.

Comment by keitha — April 25, 2008

I have no problem with the proposal and love it. What I do have a problem with:

Why is it ok for Apple’s webkit to introduce non-standard functionality, but it’s a shame if Microsoft does? IE has tons of non-standard functionality, in some cases functionality which can be quite useful, but because this functionality is non-standard, everyone in the community slams Microsoft for trying to innovate beyond the boundaries of standards. Yet when Apple does it we embrace them for it.

PS: I use Firefox, and think IE is crap, but I just wanted to point out the obvious double standards the web development community has.

Comment by PuckPuck — April 25, 2008

I’m pretty sure that the answer for why WebKit can introduce new features, is that WebKit already has (or is very close to having) all of the standards implemented.

When you are at 100%, you can start doing bonus stuff. When you are at 70%, you better worry about getting to 100% first.

Comment by Jon Hartmann — April 25, 2008

Unfortunately the non-capable browsers will be the vast majority at least for a while. I see that the proposal hints to this migration plan:

.data, div.entry {
margin-left: 30px;
margin-left: var(myMargin1);
}

IMHO this suffers from two defects: it is not maintenable as it requires the duplication of every declaration involving a variable and it adds more lines to the CSS, increasing the file size and the page load time.

Variables are a nice idea but given this implementation I’ll probably stick with literals for the next 4-5 years until the last non conformant browser dies out (btw, will we ever get rid of IE 5-6?).

Luckily there might be a way out from this situation. What I want to do is write the CSS only once and have a module in the web server that automatically generates and caches a non-variable CSS file for all the browsers that are not known to support variables. It would be a nice if the variable capable browsers add an Accept: css-variables header in their requests.

Comment by pmontrasio — April 25, 2008

Excellent idea, this is what CSS needs. Old browsers will be a problem, but it should be quite easy to ‘generate’ a ‘classic’-css version out of the new ones.

Why not go al the way and go more OO?

@corporateFont {
color: #FF0;
font-size: 10px;
font-family: serif;
line-height: 20px;
}

@corporateText {
@corporateFont;
color: #FFF;
}

p {
@corporateText;
background-color: #000;
}

.do {
@corporateFont;
font-size: 9px;
}

Comment by ronselling — April 25, 2008

“Why is it ok for Apple’s webkit to introduce non-standard functionality, but it’s a shame if Microsoft does?”
.
Because web developers don’t understand the differences between strict adherence to standards on the one hand, and interoperability on the other hand. Or that we should be demanding the latter rather than the former. Because the demand of the former creates an inevitable hypocritical contradiction between what we want and what we demand.
.
Incidentally this is an excellent subject in which to bring up the standards vs interoperability issue, as CSS variables has been in demand at least as long as web developers have been standards advocates. The two demands have lived in conflict as long as either has been around.
.
The problem that IE and Netscape(!) created was that they were not only advancing new non-standard extensions to HTML, CSS and Javascript but that they were doing so in ways that were mutually incompatible, rapid-fire and often incompatible with short lived previous versions of their own browsers. What this meant was a web which was not only non-standard but absolutely devoid of de facto standards, until IE6 stagnated.
.
There is nothing at all wrong with, and should be nothing objectionable about, sensibly introducing non-standard extensions in the context of the web. Especially given that the web standards process is almost entirely dependent on current practice, it’s likely that these extensions will eventually either become actual standards or will become de facto standard by widespread browser adoption, within a browser generation or two. And especially being that their approach is actually within the scope of existing standards: they advance proposals for that which they want to see made standard immediately, and that which is unstable gets a UA-specific prefix like -webkit- or -moz- or -o- or -ms-.
.
@Jon Hartmann: I really don’t think Webkit is anywhere near 100% standards compliance. That said, it’s definitely the most standards compliant of the current generation of browsers.

Comment by Trevor — April 25, 2008

@PuckPuck
I think that is a combination of everyone being sandy with having to work around IE6 along with the vocal portion of the web community tends to have a hard-on for Apple products. IE7 has good standards support (not 100%, but close) so I don’t see that as being a convincing argument as to why its acceptable for Apple but not Microsoft. I agree that it is a pretty unfair double standard, and honestly I’ve never seen what the big issue about extra non-standard functionality is anyways, how is the web going to advance if no one tries anything? Are we just supposed to wait five years for another standards proposal?

Comment by posure — April 25, 2008

there is another way to accomplish CSS variables, though it is of limited usefulness, and that is to use XML Entities.

Works in Opera and firefox, and I expect IE in standards mode as well as Webkit(don’t have IE or webkit at home to test with), but it only works on inline stylesheets not those referenced with elements.

Something like this make sure it is served as xhtml or it won’t work.

]>

h1 { color:&h1color;;}

I should be red!!

Comment by JasonP — April 25, 2008

To me this just adds more complexity to something that by design, should be simple. CSS is a collection of style declarations, nothing more, whether you have 1 declaration or 100 that is still all it really is. By their very nature, adding variables to anything makes that thing less stable and more complicated. I guess the possible benefits of adding a variables to CSS do not equal the possible issues.

Comment by vcarter — April 25, 2008

There is no reason to do this, to make CSS 1% of a programming language. You can already combine selectors to give umpteen elements the same color. And you can also compress the .css, so the argument that this would make the resulting CSS smaller has no merit. Finally, a robust system should keep its style in a seperate data store than CSS, for example a database, XML file, etc. and generate the CSS from it, using a REAL programming language, with variables and many other usseful programming constructs.

Comment by JonathanLeech — April 25, 2008

So Apple calls it @variable… later on in life Mozilla decides that calling it @var makes more sense. Some other time, Microsoft decides, that all you need is something like a dollar sign ($) or pound symbol (#) to define the variable.

All browsers are supporting a variables syntax, and are in effect evolving the standards, but they are mutually incompatible. This is exactly what happened with IE (5/6), Netscape, and later on Firefox.

I am all for evolving the standards, but, it should be done in a way that all competing vendors are in full agreement with, or is quickly adopted by the standards body.

Maybe this just points to a deeper bigger problem, in that standards body are far too slow to react. Standards bodies, should be proactive, not reactive, and because they are the inverse we will continuously be doing the browser wars thing. So maybe the problem isn’t Microsoft, or Apple, or Mozilla. The problem is W3C and company.

PS: If Microsoft said they were doing this with standards compliant IE8, everyone here would be saying how Microsoft needs to stop creating their own standards… that’s a double standard.

Comment by PuckPuck — April 25, 2008

Alex Russell already wrote about this plus the idea of rule inheritance: http://alex.dojotoolkit.org/?p=625

Comment by cb1kenobi — April 25, 2008

CSS variables are certainly a much desired and needed feature. I hope this proposal get’s some real consideration, and perhaps even some useful comments by the other browser vendors.

It doesn’t really matter who brought it to the table, it’s decent proposal, that deserves attention from both browser vendors and the standards bodies.

Comment by MorganRoderick — April 25, 2008

I agree with PuckPuck to a certain extent.
When people dump on Microsoft they don’t say… we don’t like your idea… they just tell MS to stop doing anything outside the standards.

If you force everyone to wait for something to become standardized you kill innovation but… innovation must follow certain rules… extend on the standard without breaking the standard. It should stick to the philosophy behind the standard.

But the thing is you cannot play with your toys before you clean up your room. I don’t think this kind of stuff would have been acceptable from MS before seeing as they were doing so poorly with the standards… you don’t try your hand at extending the standard if you can’t implement it properly to an acceptable level.

Comment by JeromeLapointe — April 25, 2008

I don’t think that CSS variables are needed that much; we already can do things like declaring CSS on a [insert-your-language-here] page and then serve it using the text/css MIME type. So, you can combine all the power of [insert-your-language-here] with your CSS.

Ok, this possibility isn’t always true, you also need to do the things in the static way. But, i’ll be lots of times more satisfied when (and if) CSS3 become fully-implemented (ok, 80% is enough by now :) ) on IE.

Comment by HudsonTavares — April 25, 2008

Like Tora said, I’ve never really needed any CSS variables — just overlap your definitions like in his example.

Comment by mdmadph — April 25, 2008

OK, this is just plain stupid… there’s no need for it at all, we can already do this with stuff that exists within the standard using entities, so why would we want another non-standard way. True, the entity way doesn’t work for external stylesheets, but if we want to fix that we should think first of what we already have and see the point where it fails: Referenced CSS is not interpreted as an XML string, but rather a flat text. Does this make sense? No, it was simply done because it was easier. So instead of doing this abomination we should redefine external CSS files as XML text nodes, which wouldn’t change anything for existing code AFAIK (I might be wrong here, but I don’t think there are any valid CSS characters that need to be escaped in XML), but would allow for this and other benefits of XML. At the same time this should be put up as a recommendation so that others can implement it in a similar fashion. If other vendors adopt it, it should become a required part of any future XHTML standard

Comment by Hans Schmucker — April 25, 2008

Regarding the so-called double standard for Safari and Internet Explorer, the issue is not as simple as most people are trying to reduce it. Trevor makes a good point about the difference between standards and interoperability.
¶
Someone else mentioned that we would rather IE be playing catch up right now rather than trying to innovate. This is another incredibly good point.
¶
Also, I am truthfully a little weary of IE innovations in general, not so much because their ideas may be bad, but because IE’s implementation of even their own ideas is often rather poor and unintuitive. In the last five thousand lines of JavaScript I have coded over the last few months, 90% of the workarounds are for IE. About 7% of the workarounds are for Opera, and about 3% are for Firefox. For Safari I have not written a single workaround. To date Safari does exactly what I expect it to do, and faster and more smoothly then any of the other browsers.
¶
Safari has my full support to innovate right now. Firefox does for the most part. Opera just made some much appreciated speed improvements for graphics intensive applications in 9.5b2, though I would like to see more work in this area, but they too have my support in innovating. IE on the other hand is way behind in interoperability and in support of standards. They are still trying to pretend that and SVG do not exist.
¶
I don’t know if there is a term for creating things that don’t do what the user expects, but Microsoft has raised this to an artform. You do 1+1 and are certain the result will be 2, but instead Microsoft returns 1 – MS + foo in one situation, 1 + PI * foo in another, and so on, but never 2. It takes a hundred extra lines of code to get MS to output 2. Part of this seems to be due to a lack of testing before releasing functionality. Part is due to not getting enough developer feedback, i.e., MS has shown a rather low interest in developer feedback in general. Part is also due to MS treating developers like children and trying to guess or interpret what result they really want, rather than simply giving the logical result. If I ask for 1+1, I really want 2. I don’t want MS to try to guess why I am asking for 1+1 and thus give me 1 – MS + Foo. I worked with .NET for almost a year, and refuse to ever touch it again for this very reason. There seems to be multiple contributing factors involved in MS not giving precise, intuitive and consistent results.
¶
With Safari, I never have to think about Safari. As the coder I feel in command. I say do this, and it does it, and it does it really well. With IE I may have to spend several hours each day trying to find the right way to ask it to do what I am asking of it. I ask for blue and it shows me a picture of an elephant. It is like IE has a mental handicap.

Comment by GregHouston — April 25, 2008

I like the way commenter ronselling does it above since it allows combining multiple rules. On the other hand, we can take the microformat philosophy and not introduce any new variables or language additions. We should simply be able to do this:
.corporate-font {
font-family: arial;
font-size: 1em;
}
.corporate-text {
color: red;
}
.corporate {
.corporateFont;
.corporateText;
}

Comment by ded — April 26, 2008

First of all, when Microsoft introduces “new features” to the standards, it’s proprietary. When Webkit introduces something new, guess what, you can download the source code and see how they implemented it. Because Webkit is open source, any other browser vendor can down load Webkit’s source to see how they did it and then implement it in their browser. And the Webkit team is not just Apple, it includes Adobe, Nokia, Google and many smaller players in the open source world.

Comment by rbiggs — April 27, 2008

ded,

.corporate-font {
font-family: arial;
font-size: 1em;
}
.corporate-text {
color: red;
}
.corporate {
.corporateFont;
.corporateText;
}

this was how I always imagined it! Never thought of variables in CSS.

Comment by AotearoanBlue — April 27, 2008

Oh joy, another layer to debug. :P

Comment by simplehack — June 30, 2008

Variables alone wouldn’t sell hard. But expression is a must. Imagine I define a standard margin for all my paragraph, I want to be able to have double margin with expression

2 * val(@margin_variable)

and gosh, it is getting more complex. Variables require their accompanion expression, access to DOM values and so on.

Comment by wendyslash — July 1, 2008

#
#
@variables {
#
CorporateLogoBGColor: #fe8d12;
#
}
#

#
div.logoContainer {
#
background-color: var(CorporateLogoBGColor);
#
}
#

This code is not working properly. please give another or complete code so that we can use effectively.
cheers :)

Comment by Ajaxester — July 9, 2008

Leave a comment

You must be logged in to post a comment.