Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Are there any agressive CSS Minification tools?

Are there any agressive CSS Minification tools?

Problem

I'm wondering if anyone knows of a tool that will aggressively rewrite CSS to compress styles more efficiently. e.g. I'd like:

.foo { color : red; font-size: 16px; height: 20px; }
.bar { color : red; font-size: 16px; height: 30px; }

to be compressed to:

.foo, .bar { color : red; font-size : 16px; }
.foo { height : 20px; }
.bar { height : 30px; }

To be clear, all the minifiers I know of, like YUI Compressor, only remove white-space and possibly join a few properties (like font-family and font-size into font). I'm looking for something that's willing to do a complete re-write of the structure of a file.

Short of that, if anyone knows of any work anyone has done with regards to the compression logic behind this, that info would be appreciated. I'm thinking of writing my own if I can't find one, but there's a million things to consider, like margin-top over-writing part of margin, selector specificity & include order, etc etc etc... Then the job of how to efficiently compress the info, like will it be more efficient to repeat a selector or a property?

Problem courtesy of: Mark Kahn

Solution

I don't know any aggressive CSS minification tool, but you could use the following approach:

Setup

  1. Expand your CSS (margin:1px 0 0 0; to margin-top:1px; margin-left:0px;...).
  2. Build a graph G = (V,E) with V as set of vertices and E as set of edges:
    • V consists of the conjunction of the two sets A (unique selectors, eg. div, p > span, #myid) and B (unique properties, eg. display:block;, color:#deadbeef;).
    • E consists of all associations between a selector (in A) and a property (in B).
  3. Use an appropriate weight function c for your elements in b. This could be the number of neighbors of a given element b, or accumulated lenght of properties - accumulated length of selectors. Your choice.

You may notice that by using this approach you'll get a bipartite graph. Now try the following greedy algorithm (pseudo code):

Algorithm

  1. Take an element b in B that has maximum weight and add it to an empty set Z
  2. Check whether another element d in B has same weight
    • if such a d exists check whether it covers the same selectors.
      1. If d covers the same selectors: add d to Z and go to step 2.
      2. if d does not cover the same selectors check the next element with the same weight or go to step 3 if you checked all elements d.
  3. Now Z is a set of properties covering some selectors. Parse this as CSS into a buffer.
  4. Delete all elements in Z and their adjacent edges in G and delete Z itself.
  5. If B is not empty go to step 1.
  6. Your buffer contains a pre-minified CSS code. You can now merge some properties (eg. margin-top:0px;margin-left:1px).

Remarks

Please note that the actual compression depends on your weight function. As it is a greedy algorithm it will likely return a minified CSS, but I believe someone will post a counterexample. Note also that you have to update your weight function after deleting the elements in Z.

Runtime estimate

The algorithm will always terminate and will run in O(|B|^2*|A|) if I'm not mistaken. If you use a heap and sort the properties in each adjacency list (setup time O(|B|*|A|log(|A|))) you'll get O(|B|*|A|* (log(|B|)+log(|A|))).

Solution courtesy of: Zeta

Discussion

View additional discussion.



This post first appeared on Node.js Recipes, please read the originial post: here

Share the post

Are there any agressive CSS Minification tools?

×

Subscribe to Node.js Recipes

Get updates delivered right to your inbox!

Thank you for your subscription

×