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.
How do CSS variables work?
Using CSS variables is pretty simple, lets dive right in and look at an example:
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).
Optimizing CSS
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:
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”:
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.
Are CSS variables a solution?
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:
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):
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.
So what are the benefits?
- Clearly structured CSS
You might argue that your CSS will be less readable because you don’t see the actual value of the css property you are looking at. This is a valid concern, but we have to realize that the benefit completely outweighs that issue (if seeing the visual effect of a class in the browser is not enough, there are great debugging tools which give you all the info you need). The fact that a developer can tell you with one look that the background color of one and all active panes is “#133213″ (paneBackgroundActive: #133213;) – that is all Tab panes, Accordion panes, etc. etc. – will improve development cycles incredibly - Maintainability
The visual definition is stored in one (maybe a few more) files. A front-end developer will not have to deal with a whole bunch of un-overseeable files but can focus on pure visual definitions. Changing a visual identity is a matter of adjusting one dictionary and not hundreds of CSS files. - Documentation
One factor which unfortunately has not yet been covered by too many people is CSS documentation. This is as important as any other documentation – especially if you are developing large scale apps. Having dictionary files with visual definitions will enable you to write clear documentation.
/*
* 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.
Why is this good if no browser supports it?
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.