Web Development by Alistair Robinson

« Blog home

CSS Abstracted


May 1st, 2010 2 Comments

Half way through the development of my last site I decided to use PHP files for CSS. I had a few stylesheets, and I found I was constantly going from one to the other to copy and paste hex colour codes. And then later, if I wanted to change a colour, I’d have to change it in all those different places. That really is no way to work.

The answer to this, of course, is variables (or constants), so that you can define your colours in one place. Trouble is, CSS don’t got none. In fact, CSS is lacking in several important ways. What it boils down to is that we struggle to get around the fact that CSS doesn’t work like a programming language. In other words, it’s not logical, intuitive or consistent.

Cognitive Dissonance

I’ve been saying for a while that the affection many people say they have for CSS must be born of their triumph in finally getting the bloody thing to work. I know this feeling. There’s power in there to do what you need, and it can be fun. We must get some kind of neuro-chemical reward when we creatively delve into the details of CSS and finally emerge with something approaching what we were going for.

In fact, this is a classic example of the psychology of rationalization, prompted by cognitive dissonance. The time and energy we spend on CSS compels us to believe that it is good, because if we doubted that, there would be an unacceptable inconsistency in our lives.

It’s how web developers remain sane: by lying to themselves.

There is a joy in arranging your stylesheets logically, breaking them down into sections, successfully and efficiently tackling the issues of specificity and inheritance. But this is only because there’s so much room for improvement in CSS. It’s so easy to write it badly, with repetition and redundancy everywhere. And even if you write it well, maintenance is still a hassle. Why should we have to deal with these difficulties when there already exist models and paradigms, in the world of programming, that could make things much simpler if applied to CSS?

Often you hear the objection that the abstraction of CSS is only for those who haven’t done the hard work in learning it properly. That kind of attitude stinks, in my opinion. Specifically, it stinks of self-justification, conservatism and protectionism. It is the bitter form of the rationalization that aims at avoiding conginitive dissonance.

CSS won’t be around for ever. It was expedient, and learning it has been a necessary evil. A heroic endeavour, it’s true: the prominent designers, developers and standards advocates who have cracked it and shared their knowledge with the rest of us are web heroes, no doubt about it. But that doesn’t mean we should continue to celebrate the endeavour if it’s no longer necessary.

First Steps

So in my last site I put things into practice in a very basic way. Here’s config.css.php:

<?php
header("Content-type: text/css; charset: UTF-8");
   
$grey = '#aaaaaa';
$light = '#efefef';
$pink = '#e66586';
?>

And here’s the fake stylesheet main.css.php:

<?php
include_once('config.css.php');

echo <<<EOT

#blog .article a {
  color: $grey;
}

#blog .article a:hover {
  color: $light;
  border-bottom: solid 2px $pink;
}

EOT;
?>

In the HTML you link to the stylesheet in the normal way, but specifying the PHP file instead of a CSS file.

True, you could use regular CSS classes for this, but do you really want to pollute your HTML with classes with names like “dark” and “box-shadow-colour” ? Just think how horrible that could get.

That’s all very well, but it’s still really just CSS. It’s also going to be slightly slower (not that I’ve noticed), and it’s a bit of a hack anyway. It’s akin to the way that PHP is peppered through HTML, and that’s not a great model.

That’s where CSS compilers or frameworks come in. One example is CSScaffold. With Scaffold you can use mixins to group together properties into reusable chunks. They work a bit like functions or classes in programming, and Scaffold comes with lots of them ready to use. Also, the big advantage of Scaffold over the way I described above is that it will serve the generated CSS files directly if they’ve already been cached.

Enter Python

But Scaffold still stubbornly clings to the CSS syntax, and it wants you to integrate it into your code. What I really wanted, as well as relief from semi-colons and curly braces, was a way of generating CSS, not on the fly in production, but only during development, so that the live site would only ever serve plain old CSS files with no server processing. So I became much more enthusuastic when I found CleverCSS, which is a way of doing this kind of thing with Python.

This…

grey = #aaaaaa
light = #efefef
pink = #e66586

#blog:
  width:450px
  float:left
 
  .article:
    margin: 10px 0

    a:
      color: $grey - 76

      &:hover:
        color: $light.darken(50%)
        border-bottom:solid 2px $pink

…on the execution of clevercss.convert produces this…

#blog {
  width: 450px;
  float: left;
}

#blog .article {
  margin: 10px 0;
}

#blog .article a {
  color: #5e5e5e;
}

#blog .article a:hover {
  color: #777777;
  border-bottom: solid 2px #e66586;
}

A few things to notice in the CleverCSS code: no semi-colons or curly braces; the indentation defines the hierarchy; the use of the ampersand to refer to the parent element for the hover; the arithmetical expression $grey – 76; and the method call $light.darken(50%).

I’m beginning to use this now to generate and update CSS files as I develop a WordPress site. If I find that it’s not right I can easily switch over to something else, or just go back to doing CSS directly – with no harm done and no time wasted.

But CleverCSS is in Python, not PHP, so I can’t very easily weave it into the fabric of the operational code, even if I want to. Instead, here’s the technique I’ve come up with:

1. Let’s say in my CSS folder I’ve got main.clvr and forms.clvr, which never get uploaded to the web server*
2. I do the styling code in these files
3. When I want to see the changes to the web page, I run a Python script from the command line in the CSS folder:

$ make_css.py

4. Now I’ve got main.css and forms.css

*Note that you can use any extension you want

Here’s make_css.py:

import clevercss
import os, fnmatch

clevercss_files = fnmatch.filter(os.listdir("."), "*.clvr")

for file in clevercss_files:
  f = open(file, "r")
  css = clevercss.convert(f.read())
  parts = os.path.splitext(file)
  f = open(parts[0] + ".css", "w")
  f.write(css)
  f.close()

This finds all the CleverCSS files and runs clevercss.convert on their contents, writing the output of each to a CSS file.

I’m really enjoying this technique, but it isn’t perfect. Running the script is an extra step, and that in itself might be enough to put some people off. And CleverCSS, at least the version I have, has no support for custom functions, mixins or macros, as far as I can tell. And debugging in Firebug is on the generated CSS, so you have to relate it back to the CleverCSS yourself.

As it happens, these problems are solved in CSS compilers such as Compass, which uses the SASS language. SASS is comparable to CleverCSS but seems to offer a bit more, including mixins. Compass takes things further: it has a bunch of standard mixins and plugins, support for grid frameworks like 960.gs and Blueprint, and it can integrate into several web app frameworks. Also, it listens for changes to your files so that you don’t have to repeatedly run a script to produce the actual CSS.

But I’m not ready for that kind of commitment. In any case it would be unsuitable for a WordPress site.

I’m very new to this methodology so I’m not necessarily recommending it. The debates continue about whether CSS itself should eventually provide these things, and whether CSS abstraction is just for programmers and not designers – but in principle I believe it’s a step in the right direction.

I’ve only mentioned a few of these languages and frameworks, but there’s a tonne of others out there, all with different syntax. An argument could easily be made that they’re just adding another layer of clutter, when we’ve no idea what’s going to happen with web standards and browsers. These solutions are transient and half-baked, and far less established than CSS itself.

However, used as a convenience in the way I’ve described, it doesn’t introduce any difficulty into development or obscurity into the finished application, which remains just PHP, MySQL, HTML, JavaScript and CSS.

Over the last couple of years there’s been a lot of activity around this. Here are some great articles, with good debates in the comments:
What’s Wrong With CSS
The Demise of Plain CSS
Why Stylesheet Abstraction Matters

CSScaffold
CleverCSS
SASS
Compass

Tags: , , , , , , , ,
Posted in web development | 2 Comments »

2 Responses

  1. That’s a really neat idea.

    It is a shame that you can’t setup colour palette ‘variables’ in CSS like you do in Illustrator. Life would be so much simpler then.

  2. Alistair says:

    Thanks for the comment Matthew. Yeah, exactly – I don’t think these things are alien concepts to designers.


©2010 Alistair Robinson