3 ways to compress CSS files using PHP
Posted by Jean-Baptiste Jung on Dec 19, 2008 | 60 commentsWhen you’re using a sophisticated design, CSS files can quickly become very long, and takes time to load. I have compiled 3 interresting ways of compressing CSS files by using PHP.
The Paul Stamatiou method
This method is the first I learnt, one year ago or so. In order to achieve it, you first have to rename your .css file to .css.php.
Make sure to import it in your html file by using their new name:
<link rel="stylesheet" type="text/css" media="screen" href="/style.css.php"/>
Once you successfully rename your css files, edit it and add the following code at the beginning of the file:
<?php if(extension_loaded('zlib')){ob_start('ob_gzhandler');} header("Content-type: text/css"); ?>
Then, add the next line to the very bottom and save the file.
<?php if(extension_loaded('zlib')){ob_end_flush();}?>
That's all. While this method is useful and efficient.
→ Source
The Perishable Press method
Basically, The Perishable Press method works as Paul Stamatiou's method, by renaming your .css files to .css.php (or .php alone) and adding this short code snippet on the beggining of your CSS file:
<?php
ob_start ("ob_gzhandler");
header ("content-type: text/css; charset: UTF-8");
header ("cache-control: must-revalidate");
$offset = 60 * 60;
$expire = "expires: " . gmdate ("D, d M Y H:i:s", time() + $offset) . " GMT";
header ($expire);
?>
I prfer this method this method to the one described by Paul Stamatiou because you don't have to edit both the beginning and the end of the css file.
→ Source
The Reinhold Weber method
I just stumbled upon this code snippet by German developer Reinhold Weber some minutes ago. The least I can say is that I like it.
<?php
header('Content-type: text/css');
ob_start("compress");
function compress($buffer) {
/* remove comments */
$buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
/* remove tabs, spaces, newlines, etc. */
$buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer);
return $buffer;
}
/* your css files */
include('master.css');
include('typography.css');
include('grid.css');
include('print.css');
include('handheld.css');
ob_end_flush();
?>
Why I like it? Because it is the only one of the 3 methods above which doesn't require you to rename the CSS files to .php. Very nice to use on an existing site. The regular expression to strip out css comments is very nice too.
→ Source
You probably guessed it, my favorite method of the 3 above is the last one. And you? Did you already tried any of theses methods? Which one is your favorite? Tell us in the comments.







Click here for demo and more info
Excellent Tip! I’ve seen the Perishable one before but the RWeber version is slick. Thank you!
Thanks a lot for this. I was looking for this one.
I’v used a combination of the three methods:
- Create a hash of the css files used
- Check if a file with that hash exists, if not:
- Concat and minify (i.e. remove whitespace and comments like in the Reinhold Weber method) the contents of the css files
- Cache the resulting data in a css file within the webroot
- Add a link to that file in the resulting HTML file
The resulting file is served by Apache using mod_expires to set the right expires header (+1 month) and mod_deflate to gzip the output. The hash created contains information about the version of the file so when the css contents change a different filename will be generated.
@Taco: Seems very interesting, I should try it sometimes. Thanks for sharing
No matter which method you use, you might want to add these headers so browsers can cache your css file. If not, browsers will end up re-querying the compressed css and that may cause an overhead on server side.
$offset = 60 * 60 * 24; // Cache for a day
header(’Content-type: text/css’);
header (’Cache-Control: max-age=’ . $offset . ‘, must-revalidate’);
header (’Expires: ‘ . gmdate (”D, d M Y H:i:s”, time() + $offset) . ‘ GMT’);
I didn’t even know this was possible. Is it needed if your server is running mod_gzip or mod_deflate? I was under the impression that that compressed everything.
I have played around with compressing CSS as well, and there is alot of more whitespace to kill:
- whitespace on both sides of commas ,
- whitespace on both sides of curly brackets {}
- whitespace on both sides of colons :
But: You can do alot more than just removing whitespace:
Remove ending semicolons:
.class {color: #000; } becomes .class{color:#000}
0.90em compresses to .9em
0px, 0%, 0em etc all compresses to 0
Then you can of course combine stuff to use shorthand syntax:
#ffffff becomes #fff
padding: 2px 0 2px 0 becomes padding: 2px 0
background: url (’image.gif’) no-repeat right center becomes background:url(image.gif) no repeat 100% 50%.
You can also remove declarations of default stuff. Background position: top left for instance.
Minify is a great project too:
http://code.google.com/p/minify/
Minify will even leave your comment hacks in there.
Just get the css-class from the sourcecode and use it as a standalone tool, thats a good start!
Sorry for my bad English.
This is how I compress my css and js files:
I have 2 separated folders “/css” and “/js”
In “css” folder create a new .htaccess file and put this on it:
AddHandler application/x-httpd-php .css
php_value auto_prepend_file gzip-css.php
php_flag zlib.output_compression On
Now create a new file called “gzip-css.php” and put this on it:
For javascript is the same, only change css for js inside files and file names.
Now you have all your files encoded and don’t need to modify or change each css and js!!.
Best regards.
Cristian
I did again! Sorry.
Code pasted in: http://pastebin.com/f70402922
Cristian: Nice method there, but if you have multiple CSS-files you will make multiple HTTP-requests, and that is something you’d want to avoid. Combining the files into one file, like in the Reinhold Weber method, would be better.
Same goes for graphics. Try googling for sprites webdesign.
I used to use a system almost identical to Christian’s - however, when I started using systems like WordPress or ExpressionEngine or Habari, where css or js files might be sent from many different folders, and manually putting the .htaccess and gzip files may not be convenient, I created a different system.
I have posted about it here:
http://www.lateralcode.com/2008/12/gzip-files-with-htaccess-and-php/
@Patrick: INterresting exemple, thanks for sharing it with us! Too bad I didn’t knew it before, I should have been inclued it in this article!
Nice example from Patrick too, but again: Combining multiple CSS-files into one file really has it’s advantages.
Torkil, it is not always possible to use the combine CSS method (especially when using blogging systems), and it is always good to have backups on hand in those situations.
I am not talking about the method mentioned in this article in particular.
CSS files are loaded in sequence so that rules in later files override identical rules in previous files. As long as you combine the CSS files in the same sequence, I don’t see any situations where you would not want to or would be unable to combine CSS files.
Why not just turn zlib compression on in IIS or Apache for css filetypes?
Very interesting tips. I never thought of compressing long css files, but now i will for sure. I guess that the last one will be my favorite one as it is the simplest :-). Thanks for sharing.
Great tips! Love the last one that does not require renaming css files.
The last method does not work for me, however, the first method appears to work (I checked with phpinfo.php, so my host definitley has zlib, and using the 1st method, nothing broke, so I’m assuming it worked…)
However, the 3rd option was the first one I intended to use. Anyone know whats going on? :\
Why not just use Apache mod_deflate and avoid the overhead of using PHP every request to process a static file? Or even better if you can have something like lighttpd or thttpd to handle just the static files and compress them, even faster.
All good and well if you have root access to the server I guess.
If you want to see a spanish translation of this article:
Si dese consultar este artículo en español puede visitar el siguiente enlace:
http://www.intergraphicdesigns.com/blog/php-mysql/2009/01/gua-para-comprimir-archivos-css-con-php.html.
En este enlace InterGraphicDESIGNS traduce al idioma español esta guía para comprimir archivos CSS utilizando PHP, y además ofrece algunas observaciones para la mejora del rendimiento en cuanto a esta idea.
I did not actually try the code, but wouldn’t replacing all spaces break stuff like “border: 1px solid black;” because it would be turned into “border:1pxsolidblack;”?
Wow, I had never heard of anything like this before. What makes this benefit your site? I’m just curious before I implement the functionality.
Compressing your CSS-files makes the whole website load faster (obviously).
Combining multiple CSS-files into one CSS-file reduces the number of HTTP connections a client has to open up to read your site, and thus also decreases loadtime
For #3 above, where do you insert code for a Wordpress installation?
Shameless plug: Minify was designed expressly for this task.
@Felipe:
mod_deflate should certainly be faster than ob_gzhandler(), but if you cache pre-encoded files to disk, PHP can actually serve them faster (using readfile()) than Apache can with mod_deflate. It seems mod_deflate doesn’t cache the encoded version and has to re-encode on each request.
Beware of removing too much whitespace in CSS: removing whitespace before ‘{’ may trigger a known bug in IE6: sth:first-line{property: value;} won’t be read by IE6 but sth:first-line {property: value;} will be OK.
Excellent tips.
It’s bookmarked and I will definitely use this.
Thanks!
@Felipe: Didn’t know that! Thanks for the expert advice
@Felipe: Good to know. Bug filed.
Hi everyone,
I have never used CSS compression on my websites before. And now wants to do this. Can you please let me know… Why should we do this and at what level means what should be the minimum css file size on which we should perform the compression.
I am really looking forward to your suggestions.
Hello,
Thanks for the great article, I will try to implement the 3rd method as you suggested, although I didn’t understand where to place the code…
Regards,
Nicholas
Wouldnt this make it longer to load the css file? Every time it loaded, the server would have to decompress the css and then publish it. Im not sure exactly how it works…
great post, I will surely try these methods, my blogs are too slow ..
The best option for me was to create a php file in the same directory as the CSS files. I used the ob_gzhandler from method 2 and combined it with the comment removal and include concept from the 3rd method.
This way, I got the benefit of keeping the css extension on the files and fewer http requests with the more powerful gzip compression since my site is on a shared host that has mod_deflate turned off.
I left the file as multiline CSS so I can get an approximate line number when using Firebug to troubleshoot any layout issues. The method I pieced together will become part of my standard process. Thank you for this post.
Hm… Interesting.
Never thought such a thing makes tangible changes.
I’ll try.