CSS File Minification in C#

6/2/2009

CSS files are usually pretty riddled with white space, extra characters, etc. that are not needed to work but is simply there so we can go in and read the file. And to be honest we need to keep them that way so that we can go and modify them. It's an endless fight between size vs readability.

So how do we go about getting the best of both worlds? Well you can add a step to your production cycle and use one of the many CSS minification apps out there (such as the YUI Compressor). And they do a good job but it's another added step, you have to make sure you run it on every CSS file, etc. I find them to be a pain personally. That leaves you with minifying the file at run time. And to be honest, it's rather simple and can be done with the following function:

   1: /// <summary>
   2: /// Strips whitespace from a CSS file
   3: /// </summary>
   4: /// <param name="Input">Input text</param>
   5: /// <returns>A stripped CSS file</returns>
   6: public static string StripWhitespace(string Input)
   7: {
   8:     Input = Input.Replace("  ", string.Empty);
   9:     Input = Input.Replace(System.Environment.NewLine, string.Empty);
  10:     Input = Input.Replace("\t", string.Empty);
  11:     Input = Input.Replace(" {", "{");
  12:     Input = Input.Replace(" :", ":");
  13:     Input = Input.Replace(": ", ":");
  14:     Input = Input.Replace(", ", ",");
  15:     Input = Input.Replace("; ", ";");
  16:     Input = Input.Replace(";}", "}");
  17:     Input = Regex.Replace(Input, @"(?<=[>])\s{2,}(?=[<])|(?<=[>])\s{2,}(?=&nbsp;)|(?<=&nbsp;)\s{2,}(?=[<])", string.Empty);
  18:     Input = Regex.Replace(Input, "([!{}:;>+([,])s+", "$1");
  19:     Input = Regex.Replace(Input, "([^;}])}", "$1;}");
  20:     Input = Regex.Replace(Input, "([s:])(0)(px|em|%|in|cm|mm|pc|pt|ex)", "$1$2");
  21:     Input = Regex.Replace(Input, ":0 0 0 0;", ":0;");
  22:     Input = Regex.Replace(Input, ":0 0 0;", ":0;");
  23:     Input = Regex.Replace(Input, ":0 0;", ":0;");
  24:     Input = Regex.Replace(Input, "background-position:0;", "background-position:0 0;");
  25:     Input = Regex.Replace(Input, "(:|s)0+.(d+)", "$1.$2");
  26:     Input = Regex.Replace(Input, "[^}]+{;}", "");
  27:     Input = Regex.Replace(Input, "(/" + Regex.Escape("*") + ".*?" + Regex.Escape("*") + "/)", string.Empty);
  28:     return Input;
  29: }

The code above strips out all unnecessary whitespace from the string that is entered, removes comments, etc. We could even go in and reduce the size of hex colors if we really wanted, but I'm leaving those alone as the space savings is rather negligible. So what we would do, is set up an HTTPHandler that takes in the path to a CSS file. The handler loads the file and then calls the function above with the resulting string being the value that we return to the user. We could even improve the handler further by allowing it to receive multiple file locations, con cat the file content together and then feed it into the function above. Anyway, definitely give it a try, leave feedback, and happy coding.



Comments