It makes sense to optimize the site’s cascading style sheets (CSS), as it pages load faster, and it reduce the amount of data transferred, and just combining css files could significantly reduce requests to server. So users benefit from faster page loads and webmaster of the sites benefits from the cheaper price of the transferred data.

I have used CSSTidy on many projects. And CSSTidy is very good tool for packing CSS and it can even fix CSS errors. Sometimes, however, feel that csstidy is even a bit too wide and “heavy” tool for the CSS files packing. Thats why I decide to write my own simple PHP class for the CSS files packing.

I did some tests and it appeared that actually all the unnecessary comments, spacing and line breaks are consuming the most space. So I did simple PHP class that remove comments, white spaces, tabs and line breaks. This class can be used directly on web pages to print compressed and combined CSS files or on the command line to compress and combine files to one CSS file.

Here is the simple CSSMin PHP class

<?php

    class CSSMin {
        private $original_css;
        private $compressed_css;
        private $files;

        /* Constructor for CSSMin class */
        public function __construct() {
            $this->original_css = "";
            $this->compressed_css = "";
            $this->files = array();
        }

        /* Add file as string (path and filename) */
        public function addFile($file = null) {
            if ($file != null && $file != "" && 
                substr(strrchr($file, '.'), 1) == "css" && is_file($file)) {
                $this->files[] = $file;
                return true;
            }
            else {
                return false;
            }
        }

        /* Add multiple files array */
        public function addFiles($files = null) {
            if ($files != null && is_array($files)) {
                $ok = true;
                foreach ($files as $file) {
                    $ok = $this->addFile($file);
                }
                return $ok;
            }
            else {
                return false;
            }
        }

        /* Print original css files concatenated */
        public function printOriginalCSS($header = false) {
            if ($header) {
                header('Content-type: text/css');
            }
            echo $this->original_css;
        }

        /* Print compressed css files concatenated */
        public function printCompressedCSS($header = false) {
            if ($header) {
                header('Content-type: text/css');
            }
            echo $this->compressed_css;
        }

        /* Sets original css loop thru all added files */
        public function setOriginalCSS() {
            foreach ($this->files as $file) {
                $fh = fopen($file, 'r');
                $this->original_css .= fread($fh, filesize($file));
                fclose($fh);
            }
        }

        /* Make simple compression with regexp. */
        public function compressCSS() {
            $patterns = array();
            $replacements = array();

            /* remove multiline comments */
            $patterns[] = '/\/\*.*?\*\//s';
            $replacements[] = '';
        
            /* remove tabs, spaces, newlines, etc. */
            $patterns[] = '/\r\n|\r|\n|\t|\s\s+/';
            $replacements[] = '';
        
            /* remove whitespace on both sides of colons :*/
            $patterns[] = '/\s?\:\s?/';
            $replacements[] = ':';

            /* remove whitespace on both sides of curly brackets {} */
            $patterns[] = '/\s?\{\s?/';
            $replacements[] = '{';
            $patterns[] = '/\s?\}\s?/';
            $replacements[] = '}';

            /* remove whitespace on both sides of commas , */
            $patterns[] = '/\s?\,\s?/';
            $replacements[] = ',';

            /* compress */
            $this->compressed_css = preg_replace($patterns, $replacements, $this->original_css);
        }
    }
?>

CSSMin class usage:

<?php
    // Require once CSS min php file
    require_once("CSSMin.php"); // Fix path and Filename if you use some other

    // Create new instance of CSSMin class
    $cssmin = new CSSMin();

    // Add multiple files array (just example)
    $files = array("/path/to/css/your_first.css", "../css/your_second.css");
    $cssmin->addFiles($files);

    // Add single file (just example)
    $cssmin->addFile("your_third.css");

    // Add second single file (just example)
    $cssmin->addFile("your_fourth.css");

    // Set original CSS from all files
    $cssmin->setOriginalCSS();

    // Compress CSS
    $cssmin->compressCSS();

    // Print original and combined css with header
    // $this->printOriginalCSS(true);

    // Print compressed and combined css without header
    $cssmin->printCompressedCSS();

    // Exit
    exit;
?>

My own class compared to CSSTidy.

At this comparision I have used this site snowblind css-file. Of course I tested other files too… :)

Original CSS: snowblind.css (10.67 KB)

Packed with CSSTidy default: snowblind-compressed-csstidy-default.css (8.21 KB, Ratio 23 %)
Packed with CSSTidy highest: snowblind-compressed-csstidy-highest.css (7.51 KB, Ratio 29.6 %)

Packed with CSSMin Class: snowblind-compressed-cssmin.css (7.68 KB, Ratio 28 %)

So I think this difference between CSSTidy and my own class is not so bad. Of course if CSS contains lots of this kind marking:

a{margin-top:10px;margin-bottom:10px;margin-left:10px;margin-right:10px;}

Conclusion

In summary, a results with simple quick made class shows a surprisingly good compared to the much more developed project. Of course if you want also do something more than just compress and combine CSS files then CSSTidy is very good option, because CSSTidy can also format and fix CSS code for a higher browser compatibility. It is also worth noting that this CSSMin class has not been tested nearly as much as CSSTidy.