Never, ever I will write plain old CSS, nesting rules over and over and renaming all the stack when the root element has to be changed.

Imagine this monstrosity

.featured_retailers {
    border: 2px solid #FFC77B;
    width: 626px;
    position: relative;
    .featured_retailers table { width: 626px; }
        .featured_retailers td {
            padding: 0;        
            border-top: 2px solid #FFC77B;
        .featured_retailers td table {
            width: 440px;
            .featured_retailers td table td {
                border: 0;
                padding: 1px 5px;
    .featured_retailers p {
        color: #333;
        position: absolute;
        top: -30px;
        right: 0;
        .featured_retailers p img {

turning into

    border: 2px solid $bgcolor
    width: 626px
    position: relative
    table: width: 626px 
            padding: 0        
            border-top: 2px solid $bgcolor
                width: 440px
                    border: 0
                    padding: 1px 5px
        color: #333
        position: absolute
        top: -30px
        right: 0

That magic is done by cleverCSS. It is written by maniacs (they added variable and expression support but went a bit too far: who would ever want to calculate sqrt of length?) but it gets the job done.

Original authors seem to have abandoned it, but it is supported by community. I added my two cents too:

  • its calculation feature was not aware of negative numbers, trying to calculate the sum , so margin: -2px -2px was transformed into margin:-4px
  • its support for /* multiline comments */ was not working, unless they were on the same line

And for integration of CleverCSS into your Django site there is django-css project. It is a CSS and JS compressor, but the compression is not what you would be after. The point is that django-css compiles CSS with external compilers, and caches the output in a clever way.

There were few things that could be improved there:

  1. It was relying on binary commands, while using Pythonic compiler in Python would be more logical.
  2. It was leaving compiled files not only in cache, but in my source tree, near the originals.

Also, I often use inline STYLE blocks for specific templates. Why have the hassle of separating them into files? The only reason can be that if page-specific CSS is large, the browser constantly redownloads it, and it is not nice.

So I added that feature to django-css too, and now it is almost perfect tool for complex Django CSSing. You can have extended CSS files compiled and cached, no matter where it is, in LINKS or in STYLE blocks.

All you have to do is surround your STYLE or LINK with {% compress css %} tag.

{% compress css %}
<style type="ccss">
{% compress css %}

Forked Repos:

PS: Github is a very nice collaborative tool, it is fun to work with. I just like BitBucket more 🙂

This entry was posted in django and tagged , . Bookmark the permalink.

3 Responses to CleverCSS

  1. Peter Pöml says:

    Hi Tim,

    could you please integrate the following patch in your tree? It fixes a small shortcoming that itched me quite a bit today.

    Thanks! Peter

    % cat python-clevercss-poeml-comments.patch handle whitespace in front of comments poeml, Wed Mar 24 19:01:31 CET 2010

    Index: dziegler-clevercss-2272da5785fd9a5a723ea12a5d7081bec20b7c9b/

    — dziegler-clevercss-2272da5785fd9a5a723ea12a5d7081bec20b7c9b.orig/ +++ dziegler-clevercss-2272da5785fd9a5a723ea12a5d7081bec20b7c9b/ @@ -541,6 +541,9 @@ class LineIterator(object): return self.lineno, line

         stripped_line = line[:comment_start]

    + # ignore also comments that have leading space; + # stripping from the right makes sure that the line is empty otherwise: + stripped_line = stripped_line.rstrip() comment_end = line.find(‘*/’, comment_start) if comment_end >= 0: return self.lineno, stripped_line + line[comment_end + 2:]

  2. Peter Pöml says:

    Sorry, the line breaks were hosed when I pasted the patch. I put it here as a file:

  3. Hi, I tried CleverCSS recently but I encountered several issues with it’s parser engine like the problem you described with margin: -2px -2px, or trying some vendor rules like -webkit-gradient(). The developer definetly got carried away with features.

    That’s why I wrote CleanCSS. Same indentation-based syntax, without all those functionalities that added to much complexity to a great idea.

    I also figured I would not implement CSS variables since I find it works great if you preprocess the ccss with a templating engine like mako or jinja if you really need them.

Comments are closed.