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.

25 responses to “Why adding variables to CSS is a good thing

  1. Not very professional to have sheets that exceeds 1000 lines emil. better to have separate css for each component of a site and merge them together to one minified file in the deployment process….

    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.

  2. I agree with Bert that css (or HTML as you propose) should not contain variables. Traditionally these languages have been void of programming features to keep them simple. I think they should be kept that way and think the best argument that Bert makes is:

    “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

  3. I can see advantages with it as well.

    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.

  4. @Andreas: So you’re saying I’m not professional? I would say minifying something that doesn’t need to be minified is just as unprofessional. Just because Yahoo and Google needs to optimize to death does not mean everyone else needs to.

    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.

  5. Hi,

    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

  6. I don’t have any idea what you mean with variables? Do you have an example?

    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?

  7. @Pära, @Dutch: There are places where I can see variables simplify things. One place is skinning a page in different colors. Changing the skin would be made easier if there was a variable list at the top, that specified #342523 as HeaderColor. Then you could use that variable several times in your stylesheet (for borders, backgrounds…). The same goes for margins that you set several times and need changeable from one location.

    @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 :)

  8. Hi,

    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.

  9. @Jon Gilkison: I think your solution is a good one if they decide to not include that functionality in the CSS spec. The only problem I have is that PHP is just one of many languages, so I have to adapt to a slightly different template language each time. Why not implement them all to one spec as you have tried to then? That is a good idea, although each implementation will have their own extras, such as your quite useful calculations.

    What do you think about the inclusion of CSS Variables?

  10. @Andreas: For performance reasons, you will ideally want to serve only one CSS file per page. If you want to separate the CSS file into multiple separate files, then you should write a build script that combines them all into a single file when deployed to the production website. You can still keep separate files for local development, if you like.

    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%;
    }

  11. @Jonah Dempcy: Sorry, wordpress destroyed your code, I couldn’t restore it by guessing :( I see what you mean though. I tend to have one file for IE hacks, and one for all other browsers. Then again, I only support IE6 and IE7.

  12. When you say variables, I hope you mean symbolic constants? In that case, I agree that they might be useful. The semantics of such constants (regarding e.g. @include rules) might be complex enough, without considering changing values as well.

    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.

  13. @Rasmus Kaj: Yes, I mean symbolic constants. They are called CSS Variables in the proposed spec, that’s why I used that.

    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?

  14. I can see the benefit. Adding variables on the presentation level should give one the opportunity to stop using “variables” on the content level.

    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?

  15. I’ve always been a fan of CSS-constants (they are constants are they not? They never change during run-time right?) but I’m not so sure they should be in there by default.

    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?

  16. @Andreas: Yes, constants is a better name, I just picked the name used in the references file.

    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…

  17. Thanks for the reply. But you never answered where you would find HTML-constants useful? Surely you don’t specify colours in your markup?

    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.

  18. @Andreas: Ah, I read CSS-constants. HTML constants is something that I use every day, in different languages. In some they are called includes, in some they are masterpages and contentplaceholder, but they are all the same: Reusable components of HTML.

    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!

  19. I do like the idea of CSS constants, but I do sympathize with Bert. However, I don’t agree with the idea of having to develop per-language solutions for a CSS variable alternative.

    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!

  20. @Henrik Lissner: That is an interesting idea. The only bad thing about it I can see is that it must be a mess to maintain for people. If you’re using generated code you better give away your generator, and the original file too. Perhaps a website with your generator that people can use? That could in fact be a rather good solution for now.

  21. @Emil: Yes, I did put that into consideration when I first thought it up. What I ended up doing was I set up a private web service, to which the CMS’s I’ve developed POST full stylesheets and receive the rewritten version (subsequently replacing the local stylesheet).

    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.

  22. I think the issue not about using variables, but rather about having the ability to define named constants. The arguments that you make about setting the same margin values over and over again are a cry for named constants. There is a place for these in any language, stylistic (as in css) or otherwise. Given that numeric constants (numbers) were created to replace the more vague concepts of one, a handful, more than handful, many, more than many, etc, the use of named constants to allow for quick and easy manipulation and maintenance of an otherwise complex system just makes sense.

Comments are closed.