A few months ago, Daniel Glazman and David Hyatt have written a proposal for CSS variables. This is a great step forward and hopefully we will find cross browser implementations some time soon.
In this article I will show how you can use CSS variables to optimize CSS. In the second part of this series you will learn how to use CSS variables efficiently in themeing applications (using the Dijit themes of the Dojo toolkit) and in the last part we will take a look how we can deal with all the new technology and convert it into a cross-browser solution with the help of a little bit of server-side magic.
Using CSS variables is pretty simple, lets dive right in and look at an example:
1 2 3 4 5 6 7 8 9 10 11 | @variables { CorporateBGColor: #123123; } #logo { background: var(CorporateBGColor); } #contact { background: var(CorporateBGColor); } |
Thats all there is to it (I admit there are a few more things but I leave those to you to find out – for now. The next blog post will cover it in more detail).
When writing themes for toolkits, creating new visual identities, or designing complex websites you will notice that you will use the same CSS values over and over again.
CSS already provides you with a lot of granularity, you are able to separate content from visual appearance, but there are still many cases where you will find yourself repeating things over and over again.
Usually front-end developers tend to move in two directions:
1. Describing the visual appearance of a an element by trying to be as descriptive in regards to that element as possible:
1 2 3 4 5 | .shoppingBasket { color: #000333; background: #fefefe; border: 1px solid #ccc; } |
The respective shopping element would then look as follows:
2. Describing an elements visual appearance by using several classes which can be used in a wider context and are combined to create a “visual event”:
1 2 3 4 5 6 7 8 9 | .borderActive { border: 1px #ccc solid; } .backgroundActive { background: #fefefe; } .textDefault { color: #000333; } |
The respective element would then use the classes as follows:
You already will have noticed that just taking one of the two roads will result in suboptimal CSS in regards to code beauty-ness, maintainability and performance.
Using the first route you will find yourself using the same “background: #fefefe;” all over again and taking the second road you will find yourself trying to create as much granularity as possible losing the larger overview.
Most front-end developers usually take the middle path, a mixture of both those techniques and this is good. Though many times – and especially in the cases of large cooperate themes, websites and toolkits – it is not optimal.
Lets just take a look at following implementation of above usecase, using CSS variables.
First we will create a dictionary with the visual identity (dictionary.css), containing all CSS variable definitions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @variables { backgroundActive: #fefefe; backgroundHover: #fff; /* ... */ textColorActive: #000333; textColorHover: #333000; /* ... */ borderDefaultWidth: 1px; borderDefaultStyle: solid; borderDefaultColor: #ccc; /* ... */ } |
Now we will implement those variables in the master CSS file (layout.css):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | .shoppingBasket { color: var(textColorActive); background: var(backgroundActive); border-style: var(borderDefaultStyle); border-width: var(borderDefaultWidth); border-color: var(borderDefaultColor); } .userDetails { border-style: var(borderDefaultStyle); border-width: var(borderDefaultWidth); border-color: var(borderDefaultColor); } /* ... */ |
The respective element would still look like following:
The benefit of this approach will clearly get visible when you are starting to deal with more than 10 classes. Envision a project with hundreds of classes, many of them describing similar things but not the same.
1 2 3 4 5 6 7 | @variables { /* * used by the entire applications text * unless overridden by another variable */ defaultTextColor: #123321; } |
The exact specification of how to document CSS best is a different discussion, there are already projects existing which are trying to push into that direction.
Since at the moment of writing only Webkit nightly is supporting CSS variables you might wonder why this whole thing should bother you at all.
The first step we should take is trying to abstract and generalize even more when we write CSS – not in the way as I described in the two examples at the beginning of this post but in the “CSS variable way” I described in the above example.
Once we understand this we can decide whether it is worth shifting our development process to using CSS variables (this is not an easy decision, there is no (non-nightly) browser out there supporting it).
Until CSS variables are widely supported by browsers you could write a simple parser which would do the search and replace for you on the server, you would actually be serving plain old CSS files.
We will look into those possibilities in the next article using tools which allow you to preview a visual identity in real time, using the Dijit widgets and converting the CSS variable dictionary into plain CSS files on the server in the last article.
Comments
Hello webmaster
I would like to share with you a link to your site
write me here preonrelt@mail.ru
March 3, 2009 — 02:36 pm
Alexwebmaster
Hi,
Is it possible to pass a variable from javascript to CSS?
My CSS looks like this:
treechildren::-moz-tree-image(makeItBlue12)
{
list-style-image: url(“http://www.google.com/s2/favicons?domain=www.nba.com”);
}
and my JS like this:
prop.AppendElement(aserv.getAtom(“makeItBlue12″));
everything works fine however I wish to pass the domain (in this case http://www.nba.com) as a variable from javascript to CSS.
Is this possible?
Thanks alot
Chris
May 7, 2009 — 03:42 pm
Chris
This is the best article of the week.:)
November 25, 2010 — 12:57 am
Merideth Weant