Abstraction in CSS

By: on April 30, 2008

I’ve written
, to no acclamation, about the difficulty in factoring
CSS. After more talking to and working with people who use CSS a lot more than
I do (and are commensurately more skillful), I think the difficulty
is the level of abstraction: CSS is declarative, but it is not
very abstract.

Usually the idea with declarative
is to describe the desired outcome and let the
computer do the figuring out how. CSS only deals with mechanism.
It does abstract from the how of layout and rendering; but, I would
argue, not in a very useful way: I want to say “make sure
this image lines up”, but what I can express is “nudge the image
down by ten pixels”.

It is like navigating in a rocket ship by manually controlling the
thrusters, when a computer is perfectly capable of working out the
whole thing ahead of time. (Of course you may want to pilot the
rocket ship manually for fun’s sake – Jef Raskin noted that
lack of expressiveness was what made games fun and most other
human-computer interfaces rubbish.)

However: CSS is what we have. What can we do to make it a better tool?

We can add the ability to express intent. The simplest example is
with constants: if I could write

  @let COLUMN_WIDTH: 200px;

  #foo {
    width: COLUMN_WIDTH;

  #bar {
    margin-left: COLUMN_WIDTH;

it makes it obvious that the margin and the width are deliberately the
same. It also means that a value only needs to be
given in one place – handy for colour schemes.

Once there are symbolic values, it follows to have
expressions in value position. This is useful for layouts that
involve margins and widths in some combination:

Another way to increase bang for syntactic buck is to add in the
ability to abstract idiom: instead of

    .box .c,
    .box .t,
    .box .b,
    .box .b div {
  background: transparent url(../img/extra-box-bg.gif) no-repeat top right;
    #glass .box .c,
    #glass .box .t,
    #glass .box .b,
    #glass .box .b div {
 background: transparent url(../img/timeline-box-bg.png) no-repeat top right;
    .side .box .c,
    .side .box .t,
    .side .box .b,
    .side .box .b div {
  background: transparent url(../img/side-box-bg.gif) no-repeat top right;

we could have

 @def rounded(SELECTOR, BG) {
   SELECTOR .b div {
  background: transparent url(BG) no-repeat top right;

 rounded(.box, ../img/extra-box-bg.gif);
 rounded(#glass .box, ../img/timeline-box-bg.png);
 rounded(.side .box, ../img/side-box-bg.gif);

Of course, it is easy enough to write a program to generate CSS
using some general-purpose programming language, or even a
templating language; but I think it will be more fruitful to grow
the established language outwards. Doing so maintains hygeine
– avoiding pitfalls of the “building SQL strings” kind, for
example – and allows for analysis.

This is all wishfulware until someone makes it happen. Since I can’t
much influence the specifications or browser implementations, I’m
working on a compiler that targets plain-old CSS. Elsewhere, there
is a
for adding constants to CSS, and a proposed mechanism for
rule reuse.



  1. tonyg says:

    Being able to abstract away from the details in CSS would be really useful. How about using something like m4 as a preprocessor, to experiment with the kinds of extensions you’re imagining? (Don’t let m4’s sendmail reputation mislead you – it’s an elegant and useful general-purpose macro preprocessor language 🙂 )

  2. Ben Hood says:

    I really appreciated the succinctness of this comment:

    We can add the ability to express intent.

    Thanks for making it such an enjoyable read.

    BTW, can you turn on comment previews in WordPress?

  3. Personally I have had great success with SASS – part of HAML and in common use in Ruby on Rails projects:


    It has many of the attributes you mention, and can be run standalone for easy integration with projects in other languages, however its killer feature for me is to easily be able to refactor the specificity of an entire CSS tree easily in response to HTML changes and so make effective use of a kind of CSS namespacing – using top level HTML elements from which to start the cascade and prevent rules conflicts and style confusion as you touched on in your last article.

  4. Silky says:

    Nice idea, I think. A pre-compiler for css would certainly be the best plan.

  5. Silky says:

    And to be clear, I mean a language ontop of CSS is a good idea, not yet another annoying css-editing-ide.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>