Abstraction in CSS
April 30th, 2008 mikeb
I’ve written before, 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 languages 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:
margin-left: COLUMN_ONE_WIDTH + COLUMN_TWO_WIDTH.
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 .c,
SELECTOR .t,
SELECTOR .b,
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 proposal for adding constants to CSS, and a proposed mechanism for rule reuse.
Entry Filed under: Technology
5 Comments Add your own
1. tonyg | April 30th, 2008 at 6:19 pm
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 | May 1st, 2008 at 12:30 pm
I really appreciated the succinctness of this comment:
Thanks for making it such an enjoyable read.
BTW, can you turn on comment previews in Wordpress?
3. Liam Clancy (metafeather) | May 3rd, 2008 at 2:10 pm
Personally I have had great success with SASS - part of HAML and in common use in Ruby on Rails projects:
http://haml.hamptoncatlin.com/docs/rdoc/classes/Sass.html
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 | May 5th, 2008 at 4:44 am
Nice idea, I think. A pre-compiler for css would certainly be the best plan.
5. Silky | May 5th, 2008 at 4:48 am
And to be clear, I mean a language ontop of CSS is a good idea, not yet another annoying css-editing-ide.
Leave a Comment
Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed