Gzipping your CSS with PHP

Published in CSS on Tuesday, February 17th, 2004

Note: The "official line" on this topic is being archived and updated here.

Note: This entry was updated on the 23rd of February. A summary of the process can be found here.

History

Late last year I had the pleasure of redesigning a site that I'd coded a mere 6 months earlier. Talk about a humbling experience, it seems that I had a bad case of classitis during the first design. I spent a day removing useless extra markup, and in the end the site had much lighter and cleaner pages, with one exception: the CSS had 'bloated' from just under 7kb to just over 12kb.

Although not anything too extreme, others began to throw wood on the fire, and I began looking for a way to make things smaller. I googled for solutions, and came up with...

Apache mod_deflate.

I looked into using mod_gzip or mod_deflate with Apache. With some help from Stephen Pierzchala at WebCompression.Org, I managed to get it working at home. Unfortunately, my hosting provider wasn't in to setting it up for me. So that was it then, no compression for me, until...

'Hey, you got your PHP in my CSS!'

Unravelling in a parallel world was this thread at Webmaster World titled "Server Side Scripting in CSS Files".

Basically it talks about parsing your CSS file as a PHP document. While in the thread they were talking about customizing this and that, it hit me that this could be a workaround for my situation.

The truth is in the numbers.

So I did some testing, and sure enough it works. The CSS file for a current project, with comments, is up to 15kb. Here are the post-compression results:

The how of the code.

This part is quite simple, I think... that is, I haven't run into any problems yet!

  1. Fetch the PHP version of your CSS document by linking to your css file from a document like this:
    @import url(mycss.php);
  2. Place the following at the top of the CSS document:
    <?php 
    ob_start ("ob_gzhandler");
    header("Content-type: text/css");
    header("Cache-Control: must-revalidate");
    $offset = 60 * 60 ;
    $ExpStr = "Expires: " . 
    gmdate("D, d M Y H:i:s",
    time() + $offset) . " GMT";
    header($ExpStr);
    ?>

This code does 4 things:

  1. It uses PHP's ob_gzhandler to send compressed data. This function will first check to see if the browser requesting the file will accept 'gzip,deflate' encoding; if not it sends the file uncompressed.
  2. It sends a header for the content type of the file - in this case text/css.
  3. The next step sends a 'cache-control http header'. Here 'must-revalidate' ensures that any information that you pass along about the freshness of your document is obeyed.
  4. The final step is to send an 'Expires' header, to set an age on how long our cached file will last. Here we set it to expire in one hour.

Some References

Redux?

Though not yet extensively tested, I think that this is quite reliable. I would love to hear feedback from people. However as I don't yet have comments for this weblog, it'll have to be by e-mail. Send comments and issues to [email protected].

Added

  1. It seems some people beat me to it, I must have been distracted by Christmas: Way to compress CSS using ob_gzhandler?
  2. I assumed that concerns with taxing the server by having it also parse my CSS would be alleviated by client-side caching of the CSS document. However Tim Lucas (nice site!) points out via the CSS-Discuss list that the correct headers for caching need to be delivered as well. I've added the extra suggestion to the code posted above.

A summary of the process in 'article' format can be found here.

Comments and Feedback

I've received a few e-mails and seen a few notes and comments from other people around the web about this idea.

I wanted to mention that this method, like any tool, is a decent solution given the right situation. More robust compression methods like Apache's mod_gzip (or mod_deflate) may be favorable, but not available to everyone.

It is also worth mentioning that for smaller file sizes there may be little to no gain using this method.

Keep in mind that Netscape 4 (who would have thought?) is not able to parse gzipped CSS files.

Thanks Lars. I had added that fact to the
article
version, but it seems I missed it here!

Thanks also for posting the first ever comment on this site!

My pleasure! I found this site via Dave Shea's mezzoblue.com linking to you in his Dailies.

By the way: I decided not to put PHP in my CSS but letting Apache's mod_gzip do the compression:


<IfModule mod_gzip.c>
mod_gzip_on Yes
[...]
mod_gzip_min_http 1001
mod_gzip_handle_methods GET POST
mod_gzip_item_include file .css$
[...]
</IfModule>

Notice mod_gzip_min_http 1001. By this, .css files are only compressed if protocol is HTTP 1.1 which should be common for most modern browsers - Netscape 4 sends HTTP 1.0 and so doesn't get the stuff it can't handle.

Best regards,

Lars

P.S. Kind of difficult to post code to this article

You also need to send a Content-Encoding: gzip header.

See also: cgi_buffer, a set of libraries for PHP, Python and Perl that automagically compresses and handles caching information for you.

Mark, do you have to? It is my understanding that PHP should handle that, as it doesn't send the content zipped unless the user-agent can accept it as such.

Home » Blog » Web Development » CSS

Check out the blog categories for older content

The latest from my personal website,
Mike Papageorge.com

SiteUptime Web Site Monitoring Service

Sitepoint's web devlopment books have helped me out on many occasions both for finding a quick solution to a problem but also to level out my knowlegde in weaker areas (JavaScript, I'm looking at you!). I am recommending the following titles from my bookshelf:

The Principles Of Successful Freelancing

I started freelancing by diving in head first and getting on with it. Many years and a lot of experience later I was still able to take away some gems from this book, and there are plenty I wish I had thought of beforehand. If you are new to freelancing and have a lot of questions (or maybe don't know what questions to ask!) do yourself a favor and at least check out the sample chapters.

The Art & Science Of JavaScript

The author line-up for this book says it all. 7 excellent developers show you how to get your JavaScript coding up to speed with 7 chapters of great theory, code and examples. Metaprogramming with JavaScript (chapter 5 from Dan Webb) really helped me iron out some things I was missing about JavaScript. That said each chapter really helped me to develop my JavaScript skills beyond simple Ajax calls and html insertion with libs like JQuery.

The PHP Anthology: 101 Essential Tips, Tricks & Hacks

Like the other books listed here, this provides a great reference for the PHP developer looking to have the right answers from the right people at their fingertips. I tend to pull this off the shelf when I need to delve into new territory and usually find a workable solution to keep development moving. This only needs to happen once and you recoup the price of the book in time saved from having to develop the solution or find the right pattern for getting the job done..