Table of contents

  1. CSS Preprocessor
    1. How does it work?
    2. Goodies
      1. Catches
    3. Live examples
    4. Notes
      1. About this implementation
      2. General parser issues
    5. TODO
      1. Ideas

There are some recurring proposals for CSS that get rejected because they don't need to be implemented on client-side or browser vendors may abuse them. These are:

and here's the best part: I've started implementing them in a way that is compatible with all current browsers.

How does it work?

It's a server-side PHP5 script that parses extended CSS files, filters them and outputs valid W3C CSS stylesheets (outputs without any unnecessary whitespace, so you get light compression as a bonus).

It's not just simple regex hack. It's a real parser with CSS-specific error recovery. It even passes Acid2 test :)

Sytax is based on CSS2.1 CR—20040225. It's extended to accept some CSS3 and…

Goodies

You can write expressions instead of simple CSS terms. Just add extra parentheses:

margin-left: (200px * 3/2 – 10px);

You can define constants:

@define
{
menu-height: 4em;
gutter: 15px;
sidebar-width: (200px – gutter);
}

and use them in expressions:

#maincontent
{
padding: (menu-height) 0 0 (sidebar-width + 10px);
}

You can include files, anywhere in stylesheet. Included files are parsed as individual files, but they all share variables (this behavior might be configurable in future).

@include "file.css";

C++ comments are recognized (parser does not preserve comments except Mac IE comment backslash hack).

foo {bar: baz} // quz!

Catches

There is no public download available at the moment. The script is not ready for big time. Send me an e-mail if you want to play with the script.

Live examples

Compare:

Notes

About this implementation

Speed of this script is not an issue. It's fast enough for development, and for production sites you should use generated static CSS files anyway.

Script uses PHP5 OO features. It might be possible to change few things (most notably remove error recovery code) to get basic PHP4—compatible version, but I won't bother to do that.

CSS compression is achieved only by removal of optional whitespace and don't expect more. There are very few cases when CSS can be safely shortened, that is without affecting cascade, inheritance or running into browser bugs.

Expressions are lazily evaluated.

General parser issues

Names with hyphens are horribly confusing. I'd like to replace hyphen with a period, but that's tricky — in CSS hyphenated identifiers are a single token, so any solution to this problem would involve inelegant hacks or major changes to CSS grammar.

Single flat namespace for variables is acceptable if you name your variables in organized way (menu-heading-height, sidebar-link-color, etc.).

Structures

The next step is to add structures. Compare:

margin: (example-margin-top) (example-margin-right) (example-margin-bottom) (example-margin-left);
margin: (example-margin);

These cannot be simply arrays. Parser must know type of structure to reliably access its elements:

background: (example-background);
padding-left: (example-background-position);

TODO

Ideas

nc

border:0; border-right:nc;

is

border-left:0;border-top:0;border-bottom:0;

In

in #menu {
. {}
li {}
a {}
}

equals

#menu {}
#menu li {}
#menu a {}

Variant

@define {myFontSize: 14px;}
@define body.large {myFontSize: 20px;}
foo {font-size: (myFontSize);}

equals

foo {font-size: 14px;}
body.large foo {font-size: 20px;}