Quick & Easy CSS Compression Using PHP

By  on  

Loading time of a website is as important as its functionality. You can have a great website but who wants to wait for it to load? CSS compression can help your website load faster and easily maintain its functionality. I've created an easy-to-use PHP file to compress your CSS for optimal client download time.

The Code

The process takes place in two files: one PHP file which we call css.css (yes, use the ".css" extension) and your directory's .htaccess file.

Here's the PHP for css.css:

$css = '';
$root = $_SERVER['DOCUMENT_ROOT'].'/css/'; //directory where the css lives
$files = explode(',',$_SERVER['QUERY_STRING']);
if(sizeof($files))
{
	foreach($files as $file)
	{
		$css.= (is_file($root.$file.'.css') ? file_get_contents($root.$file.'.css') : '');
	}
}
return str_replace('; ',';',str_replace(' }','}',str_replace('{ ','{',str_replace(array("\r\n","\r","\n","\t",'  ','    ','    '),"",preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!','',$css)))));

The css.css file takes the given querystring and explodes it on a comma into an array. If there is something in the querystring (which there should be, unless the programmer messes up), which should be separated by a comma, the querystring gets separated into an array. For each string within the array, the script looks for a CSS file with a matching name. The script then appends the content of the file to a string variable ($css). Once all of the CSS content is within the $css variable, the CSS content is scrubbed of all whitespace. Less whitespace and one file means a much faster download speed since there is only one request for a compressed file.

Here's the code you'll place into the .htaccess file so that css.css gets treated as a PHP file:

<FILES css.css>
  SetHandler  application/x-httpd-php
</FILES>

The Usage

Using the css.css file is easy:

<link href="/css/css.css?reset,base,forms,template" rel="stylesheet" type="text/css" media="screen" />

Essentially, in the example above, we're looking to use reset.css, base.css, forms.css, and template.css. If one of those files doesn't exist, they wont be added (and there's no error message).

Do you have any suggestion for my script? Any ideas to contribute that would optimize the CSS?

Recent Features

Incredible Demos

  • By
    MooTools Zebra Table Plugin

    I released my first MooTools class over a year ago. It was a really minimalistic approach to zebra tables and a great first class to write. I took some time to update and improve the class. The XHTML You may have as many tables as...

  • By
    Scroll IFRAMEs on iOS

    For the longest time, developers were frustrated by elements with overflow not being scrollable within the page of iOS Safari.  For my blog it was particularly frustrating because I display my demos in sandboxed IFRAMEs on top of the article itself, so as to not affect my site's...

Discussion

  1. What about the performance of this script?
    I can imagine the concatenating the $css can get quite expensive. Maybe add some caching mechanism that wont have to reread the files and perform that nasty string replace.

    Just a suggestion. :)

  2. Thank you for contributing Jesus.

    It all depends on how frequently you update your CSS.

    You could definitely save the output of this script and simply reference that.

    David

  3. Cool script. Depending on the size of the site, I find it most efficient to incorporate the CSS packing during the build process, and release as a static CSS file. Then configure Apache to gzip output of CSS files to shrink even further ;)

  4. Nice! Just what I was looking for.

  5. What a pitty. My webserver ( one.com ) does not seem to support this usage of the .htaccess file. :-(
    Cheers, Stinie

  6. I added some code and I think it improved the compression a little bit:

    $css = str_replace(': ', ':', str_replace(';}', '}', str_replace('; ',';',str_replace(' }','}',str_replace(' {', '{', str_replace('{ ','{',str_replace(array("\r\n","\r","\n","\t",'  ','    ','    '),"",preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!','',$css))))))));
  7. I’ve used this script on my website. Thanks!

  8. Thanks, this code (and the idea behind it) was very useful. I had to change how it was output as originally the browser wouldn’t read it – could have been due to server settings. I just added this to the end:
    header("Content-type: text/css");
    echo $css

    Also the code Thomas Whilhelm posted was useful, it did shave an extra kB off the document but only after I removed the 5-7th elements of the 7th str_replace:
    $css=str_replace(': ', ':', str_replace(';}', '}', str_replace('; ',';',str_replace(' }','}',str_replace(' {', '{', str_replace('{ ','{',str_replace(array("\r\n","\r","\n","\t"),"",preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!','',$css))))))));
    With those extra elements (which came out as spaces on here) it messes up any nested CSS (i.e. most of it)

  9. CJ

    I simplified it even further and cut out as much whitespace as possible with this code. I’ve rearranged the spaghetti into a function just because I prefer it that way. Feel free to re-spaghetti.


    function compress($css){
    // Remove comments
    $css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
    // Remove spaces before and after symbols
    $css = preg_replace('/(\s(?=\W))|((?<=\W)\s)/', '', $css);
    // Remove remaining whitespace
    $css = str_replace(array("\r\n","\r","\n","\t",' ',' ',' '), '', $css);
    return $css;
    }

    • @CJ
      This compression code is great, one issue though.

      I used your code to compress and it incorrectly removes spaces after classes.

      This

      .alert .title { font-size: 15px; }

      Comes out as:

      .alert.title{font-size:15px;}

  10. Extremely simple to implement, I tried code.google.com/p/minify/ but it is very hard to adopt and implement.
    Your code is so simple and light weight to implement.
    It will be implemented in next release of my product.

    It would be appreciated if you can help me understand: what is difference between css.css to be treated as PHP rather than url rewriting?

    Cheers!!!

  11. Super helpful..
    need also to add this bit of code in order to work maybe due to some server settings like M1ke did. Thanks a lot!!

    header("Content-type: text/css");

  12. Thanks for codes,…

    but i created my own compressor.
    http://www.igloro.info/en/css_compressor.html

  13. Nicely done.

    Hey roman, if yours is different … why aren’t you showing your work? :D

  14. Myroslav

    Hi!
    There is php extension which can compress js and css files

    https://github.com/kufd/jsCssCompressor

  15. Jonas Røssum

    Thanks so much for this! I don’t know if I overlooked something, but what about spaces before “{” and after “:”?

    http://pastebin.com/LqzkuJqP

  16. Thanks, just what I needed. I used it to compress the result from the LESSCSS PHP processor like this:

    compileFile($input);
      
      echo str_replace('; ',';',str_replace(' }','}',str_replace('{ ','{',str_replace(array("\r\n","\r","\n","\t",'  ','    ','    '),"",preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!','',$css)))));  
    
    } catch (exception $e) {
    
      echo "fatal error: " . $e->getMessage();
      
    }
    
  17. David, something is going wrong with the comments.. i tried to use a PRE tag or a GIST embed, but anyway, here is the link: https://gist.github.com/gport/5116023

  18. your code is not working properly. The only option left with me is using google pagespeed service to get my css properly minified. Though your code minify css but also remove some vital information that affect our css very badly. is there any solution for this issue. Waiting for your kind attention on this issue.

  19. Another examples including HTML and JavaScript minifier in pure PHP → https://gist.github.com/tovic/d7b310dea3b33e4732c0

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!