CSS Organisation - Variables

In the previous post in this series I wrote about organising rule sets in CSS and came to the conclusion that it would be best not to try and avoid all repetition. This means that there is some additional maintenance to be done when changing values that appear in several places. In this post I will look at at the unsophisticated method I use to make this easier as well as a brief mention of some of the other more heavy duty solutions available.

My Solution

In the first post in this series, I discussed having a "table of contents" at the top of the CSS file. Below this I place a list of values used in multiple places in the document, which look something like this:

/*
* Colours used:
*
* Background Green - #8CC63F
* Text Green       - #5A8029
* Footer Grey      - #333
* Border Grey      - #CCC
*
* Dimensions
* 
* Content width - 990px
*/

This provides an easy reference point when adding a new rule which needs to use these values. This also allows for easy find and replace if a value needs to be changed.

Next Step

At Lime Thinking already do some PHP processing of CSS before serving it, for example running it through a minimiser, combining multiple file into one file to reduce HTTP requests. Since we are doing this, we could also use PHP to do some basic variable replacement, the above list could be made to look more like the following:

/*
* Colours used:
*
* $backgroundGreen - #8CC63F
* $textGreen       - #5A8029
* $footerGrey      - #333
* $borderGrey      - #CCC
*
* Dimensions
* 
* $contentWidth - 990px
*/

If the "variables" such as $backgroundGreen are then used in place of the variables in the CSS file, then PHP can be used to find and replace them with the relevant value. This would further reduce the maintenance of the CSS file, although at the step of moving away from having a CSS file that only uses CSS syntax and which can just be applied to a page without the processing.

Heavy Duty Solutions

A similar but more fully featured approach is already available in various CSS frameworks, which amongst other things provide support for CSS variables. These include

These CSS frameworks provide more than just variables, with features such as nesting selectors, mixins, selector inheritance. Whilst these may solve the issue at hand along with several others, there is a learning curve involved with any new tool like these. Much of what they provide appeals to me as a programmer but I can't help feeling that they seem like overkill. I have not fully investigated using one so far but may do at some pint in the future. Personally I have never thought that it was worthwhile learning a completely new syntax to solve some of the annoyances of CSS but then I am not writing CSS all day every day.

Real CSS Variables

There has been discussion over the years about introducing variables directly into CSS, there are many opponents to this though, citing the difficulties of doing so, e.g. dealing with multiple decelerations of the same variable in different files that are all included or imported. Additionally the fact that CSS does not contain variables and other programming devices such as if, then branching, is seen by many as a positive thing which allows easy adoption by non-programmer designers and moving away from this would be to its detriment.

Even if there was agreement on the issue, the speed at which new CSS specifications arrive and at which browser developers implement them mean it would be a long wait before they were available in practice.

Conclusion

In the cases of PHP and JavaScript I think the use of frameworks is beneficial in removing a lot of hard work, I am not going to enter into the arguments here though, apart form to say that many of the arguments that apply to them are just not true of CSS. Learning a framework for JavaScript or PHP does not require writing using a new syntax as it does with many CSS frameworks. It feels that whilst it has its annoyances CSS is just not doing something complicated enough to require this additional level of complexity. The simple method I suggested first seems more in keeping with the simplicity of CSS than some of these other solutions.