Why adding variables to CSS is a good thing
Via Simon Willison I find that Bert Bos, one of the creators of CSS, has written an article on why variables shouldn't be included in CSS3. I thought I'd try to explain why I think they should.
Professional perspective#
Bert posts statistics of stylesheet usage from the W3C site, and means that most stylesheets are very small, and on those, variables are not really needed. I agree. You can get away with simple search-replace in those simple cases. But Bert also finds that there are bigger sheets: "largest hand-written style sheet: 1462 lines (bought from a Web design company)". I work at one of those companies, and almost all CSS files I write exceed 1000 lines.
In those cases, I think CSS variables would help me a lot. Especially for margins. Matching several margins together by copying the same value over and over again isn't maintainable. Search replace on a pixel value is a sure way to mess up your whole stylesheet: who says you only use 5px for those margins? So there is a use case for some kind of variables.
So we need variables, but how?#
Bert then suggests that those people should use a solution such as PHP to generate CSS. So we should invent a new language for generating CSS with PHP? And another language for generating CSS from Ruby, from Java, from .NET, and so on. Why shouldn't we go this way? It's the path HTML has taken. And this is a hard nut to crack. How is CSS different from HTML? Why should CSS have variables when HTML doesn't?
I think the answer is that we should add variables to both languages. They are very similar in nature, so they should be treated the same. Because what has changed since when CSS was created is that we've started building bigger and more complex sites. And if CSS starts to be too cumbersome to use, people will start looking elsewhere, to Flash, Air, Silverlight and so on. CSS needs to adapt to the more complex sites people are building today.
I'd rather see CSS follow the times and add variables, than seeing frustrated professionals move to proprietary technologies.
So what about beginners?#
Bert's article deals a lot with beginners, and how it will be harder for them to understand another level of abstraction. Lets make it clear at first that CSS already is too hard for beginners. To make a very simple layout you need to understand floats (yes, almost everyone needs columns), and floating is really confusing (ever tried to explain float/clear to someone?). Even for someone like me, who has worked with CSS for years, floats still puzzle me regularly.
People will give up on CSS when they encounter floats (yes, I've seen this), not when they find CSS variables. They can just choose not to use variables, while they really need to know floats. Also, CSS variables are easier to understand than cascading values. I mean really, if I set font-size on body, why do my links get larger? That's a very similar concept that is central to CSS.
Summary#
CSS Variables make it easier for professionals to do their job. It doesn't require inventing new template languages. It doesn't make the language overall harder either. The people that can handle floats and cascading, can handle variables too. We need variables.
Comments
By: Andreas (#1)
clients are already forced to parse and execute js, adding variables in css would just add another dimension when it comes to scaling and performence. even if the browser is smart enough to cache the parsed css, it will still make your front page load slower.
If you really would have needed css vars during all these years, you would have made some solution for your self by now, because thats how pros work. They make tools for themself when the current ones doesnt fit their needs.
By: devtrench (#2)
"Even if the implementation cost of constants would be very small, it is still better to leave them out of CSS. That is a consideration for every addition to CSS: extending CSS makes implementing more difficult and programs bigger, which leads to fewer implementations and more bugs."
CSS is already under implemented in browsers and sticking this feature in could lead to more harm than good. With all of the browser implementation problems we have now I can imagine how poorly this would be implemented.
One thing I didn't see in either article (sorry if I missed it) is how variables would gracefully downgrade in older browsers. It's pretty easy to tell a parser to ignore what it doesn't know, like in the case of opacity. But I don't see how an older browser would parse something like color: $my_color. No one better suggest we make 2 stylesheets :)
My 2c,
James
By: Pelle (#3)
CSS variables would for example open up for some interesting optimizations possibilities as well - instead of having the same big values (background-images as data:urls can get particularly big) assigned at many different places it's only assigned at one place with a descriptive variable name which later an optimizer can replace with a single character.
By: Emil Stenström (#4)
It doesn't make parsing slower in any major sense. Webkit wouldn't have implemented it if it did. Bert would also have put that argument forward then. What do you base that claim on?
Lastly. I work in several different languages (Java, C#, Ruby, Python), and often under tight deadlines. When in that situation I don't sit down and construct a new template language. That would waste time for my customers, which is not how pros work.
@devtrench: The argument you picked is really an argument to not extend CSS at all. I don't agree with that. CSS3 should include more features than what we have today, features that are needed by todays professionals.
I'm not sure there is any ideas of how to downgrade at the moment. The spec talks about using color: var(myColor); and perhaps you could just have a line with color: red above that one? If if can't parse var, it drops the whole line.
@Pelle: Yep, I agree. Although that isn't the biggest gain since gzip (if you have that enabled) takes care of duplication pretty well.
By: Pära (#5)
Dont really know what vars in CSS would mean to me but i in my meaning CSS is already a, but reversed(?), form of variables.
If you for instance use "sprited" images, just register the css propery for image url once. Then add you selectors to that property set.
If accessing the same property value (say backgrounds, borders etc.) more than a few times I think one would have a fundamental problem in ones CSS.
Catch my drift?
Cheers
By: Dutch (#6)
CSS with 1000 lines? I don't have a large website, I only work for my private website, but I work with several websites, one with common lines which are used by every part, like divisions, menu etc. Other files are separate because I work with different backgrounds, menu colors etc.
Is it smart to work with several stylesheets and are there more possibilities?
By: Emil Stenström (#7)
@Dutch: 1000 lines is common since I often work on CMS:es, and those need to account for many many types of styling my editors. It isn't uncommon that there's no easy way to see what kind of page you have (article, section...) so you need to put all of them into one stylesheet. Big sites means big stylesheets :)
By: Jon Gilkison (#8)
I'm the author of the PHP implementation.
Just to clarify, the PHP version is built to the exact same spec as the webkit version and the stylesheets can be used interchangeably.
The one difference, however, is that my implementation has an eval() statement that allows you to:
padding: eval(somevar * 2);
margin: eval((anothervar / 2)*yetanother);
Personally, I don't give a rip if anyone uses it or finds it useful. We use it on a large site (massify.com) and have found it to be practical and a boon to productivity. YMMV.
Additionally, the PHP version doesn't compile it everytime, only if it has changed. There is a command line version that will compile everything to static CSS files.
By: Emil Stenström (#9)
What do you think about the inclusion of CSS Variables?
By: Prom?nné v CSS. A není to chyba? - Martin Hassman: blog nejen o prohlíže?ích (#10)
By: Jonah Dempcy (#11)
Personally, I prefer one file since I usually use inline find (CTRL+J) in Aptana to locate a given section of code. For those unfamiliar with inline find, it works the same as normal find but doesn't cause a window to popup, so you can just start typing at any time. Firefox includes this as the default find behavior (when clicking CTRL+F).
On a side not, I abhor including separate IE stylesheets. It's become commonplace now for sites to use conditional comments to include separate IE stylesheets, for instance:
<!--[if lte IE 5.5] -->
<!--[if IE 6]-->
<!--[if gte IE 7]-->
This method frustrates me because I need to open 4 separate stylesheets to see all of the rules that are affecting an element. Instead, I much prefer this:
<!--[if lte IE 5.5]-->
<!--[if IE 6]-->
<!--[if gte IE 7]-->
<!--[if !IE]-->
This allows me to write CSS rules all in the same stylesheet, like so:
#some-element {
color: red;
}
.ie #some-element {
color: blue;
}
.ie6 #some-element {
padding-top: 10px;
}
.ie7 #some-element {
line-height: 120%;
}
By: Emil Stenström (#12)
By: Rasmus Kaj (#13)
And by the way, HTML already has such symbolic constants, they're called entities. They can only be declared in the DOCTYPE, not in the page content, but they can still be usefull. Last time I used them, I made sure to evaluate them in a preprocessing step, though. Not in the browser.
And preprosessing can be useful for css as well. Plain old cpp or m4 is actually very useful, both for symbolic constants and for merging separate files to a single "end-user" file.
By: Emil Stenström (#14)
Do you mean HTML character entities? Or are there some other kind of entity that I don't know about? Another type of symbolic constant is the use of frames. It lets you divide your page into different parts and reuse them (Aside: Fun spec, found while googling).
Preprocessing can solve these issues, but if preprocessing is something you always want, no matter what language, why not work at including it in the spec?
By: Anders Ytterström (#15)
With that, I mean the use of mutliple common classes to create a presentation of a block:
<div class="nav horisontal tabbed">...>
It would be nice to instead create the css-variables nav, horisontal and tabbed in the css file(s) and use them internal. Would spare some non-content markup in the HTML.
Is this a good reason, Emil, or have did I miss the whole real part of CSS variables?
By: Andreas (#16)
They're silly-easy to implement using _any_ server-side-language and the syntax in the CSS wouldn't have to change from server-side-language to language at all so you could re-use your CSS from server to server without problem.
@Anders Ytterström - I like how you think and I had exactly the same ideas as you when I built my CSS constants PHP Class. To remove the need for classes altogether.
I'm curious to know where you think HTML-constants (or variables) would be useful?
By: Emil Stenström (#17)
Coloring is a perfect place where constants would be useful. If the client changes their mind concerning a color you just change that constant. No need for search/replace. And no need to write a Java-CSS wrapper...
By: Andreas (#18)
Also - if you wanted to change the colour-scheme of a site (at least the ones I normally code) it wouldn't require the change of one single colour. It would require changes to probably 5-10 different colours _and_ background-images so I'm not sure constants would help that much in that case.
I think the biggest benefit of constants is the one that Anders Ytterström mentions, to get rid of _all_ design-related stuff from the HTML. Classes like "box" or "self-clear" or anything that you put in there only because the current design requires it should be in the CSS - not the HTML.
By: Emil Stenström (#19)
I agree that we use lots of colors in the CSS today. The thing is, many of those can be abstracted away with alphatransparent PNG-images. If we only could get rid of IE6 they would be really usable.
Using CSS-constants like Anders suggests would be really useful, I agree!
By: Henrik Lissner (#20)
It sounds like you're saying we should be developing parsers on a per-language basis. But why not make it a pre-deployment step?
I have made my own custom solution, a quick 'n dirty php script that parses and rewrites my css files en mass. Done locally of course, and the result is uploaded. No need to do any active parsing.
Just my 2 cents! Cheers!
By: Emil Stenström (#21)
By: Henrik Lissner (#22)
The problem comes when someone doesn't get the CMS, but wants to alter their CSS files, but they usually come back to me in those cases; so I haven't had to address that need just yet.
I suppose I could simply put up a form on my site that could post to that web service. Just some food for thought.
Maybe when the project becomes more mature I will make it public.
By: Shane (#23)
By: Variablen in CSS: Werkzeuge und Lösungsansätze | Dr. Web Magazin (#24)
By: Kristoffer Nolgren (#25)
http://sass-lang.com/tutorial.html
It's a helper that supports nested css, variables etc, it works seemlessly and ofc. wont effect performance.
I LOVE the work you're doing on kundo btw!
Kristoffer, resihop