Compress CSS with PHP

Start your CSS files with this PHP (and name it style.php):

    ob_start ("ob_gzhandler");
    header("Content-type: text/css; charset: UTF-8");
    header("Cache-Control: must-revalidate");
    $offset = 60 * 60 ;
    $ExpStr = "Expires: " .
    gmdate("D, d M Y H:i:s",
    time() + $offset) . " GMT";

body { color: red; }

Then call your CSS with the PHP file name:

<link rel='stylesheet' type='text/css' href='css/style.php' />


  1. Ben
    Permalink to comment#

    Some older browsers choke when CSS files don’t have the .css extention. It’s the same with Javascript files.

    Perhaps use .htaccess to rename it to style.css

    • elandy2009
      Permalink to comment#

      Anyway nobody cares about old browsers when developing Web sites.

  2. TeMc
    Permalink to comment#

    @Ben: Or rename the file to .css and use .htaccess to interpretate is as PHP ;-)

  3. TeMc
    Permalink to comment#

    @Ben: Or rename the file to .css and use .htaccess to interpretate it as PHP ;-)

  4. Roflo
    Permalink to comment#

    I believe it’s good practice to call ob_flush(); at the end of your script.

  5. DougS
    Permalink to comment#

    how do you know so much stuff

  6. Jacob McDonald
    Permalink to comment#

    I’m glad to see my submission got up on the site.

  7. Hassan
    Permalink to comment#

    I get “Cannot modify header information” error. Any idea?

    • David
      Permalink to comment#

      You may be outputting something before the call to header().

      Usually this is because of a new line or space before the very first <?php tag

    • Praveen Kumar
      Permalink to comment#

      Check for UTF8 Byte Order Marks in your file. That causes the issue here.

  8. Bloggerschmidt
    Permalink to comment#

    Thanks for the snippet. The line

    <pre>header(“Content-type: text/css; charset: UTF-8”);</pre>

    should be

    <pre>header(“Content-type: text/css; charset=UTF-8”);</pre>

  9. cpWicked
    Permalink to comment#

    What are the advantages if i compress css?:)

  10. Michelle John

    i think you can also use gzip or defalte mod options if you are using apache server.

    • VR

      use the ob_gzhanlder() callback.
      available since PHP 4.0.4

  11. Keshav Naidu
    Permalink to comment#

    What is the uses ?
    -thanks in advance.. :)

  12. Ahmad Awais
    Permalink to comment#

    What are the advantages of it? I am using Minify stuff?

  13. Peter
    Permalink to comment#

    you could use it like this:

    $base_color = "#COFFEE";
    a {
    color: <?=$base_color?>;
  14. Dalibor Sojic
    Permalink to comment#

    This script has disadvantages. The main disadvantage is caching.

    On first visit, php will set expire date to “future”, but… if you make change into the CSS, will not reflect to returning visitors, because they already have cached CSS.

    • BAM5
      Permalink to comment#

      True, but there are other methods of caching, such as setting an ETag header and changing that whenever you change the contents of the php output so as to update the browser’s cache. Or better yet, do a checksum of the output buffer and set that as the ETag that way you never have to touch the php code, although that has disadvantages because you’d have to render the css and hash it each time to compare the ETag from the client.

      <?php ob_start ('ob_gzhandler'); ?>
      body { color: red; }
      $output = ob_get_clean();
      $etag = md5($output); // or crc32($output) which is faster but not as unique
      $headers = getallheaders(); // May not work on non Apache Servers
      foreach($headers as $header => $value)
      	if($header == 'If-None-Match' && $etag == $value){
      		header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
      header('ETag: '.$etag);
      header('Content-type: text/css; charset: UTF-8');
      echo $output;
    • BAM5
      Permalink to comment#

      Quick note, I didn’t test the above code so it may or may not work.

    • MorningCoffee
      Permalink to comment#

      Or you can use a very quick and common fix for caching, time() or something along those lines. I personally do style.php?r=md5 ( 2012-01-13_09-51pm )

      md5 hashing revision date of css so if there is a new md5 hash it will re-cache the css, since time() will force non-stop reaching which is not something you may wont.

  15. Syed Shah
    Permalink to comment#

    But any way good and very important specially when google bot visit its also check how quick is your website. I dont think this is a disadvantage. Its all upto you how to use it.

  16. Mark Kachel
    Permalink to comment#

    I can’t get the script above to css validate using v2.1 validation.
    It keeps giving me this content type error. Can anyone please help? thank you!

    The exact error:
    URI :
    -1 Unknown error org.w3c.www.http.HttpInvalidValueException: Invalid content type.
    Feel free to use the validation service from

  17. mAnisH
    Permalink to comment#

    i think it make to load the css every time page loads

    • Helly
      Permalink to comment#

      mAnisH, could you please tell me what did you do to load the css every time page loads? I could really need some help :(

  18. Dan
    Permalink to comment#

    I never stop learning in this business. I had no idea that css compression could be achieved in this manner.

    Thank You!

  19. Κατασκευή ιστοσελίδων
    Permalink to comment#

    Im using joomla with gzip but the css files are not compressed. I don’t use .htaccess bacause the server has freebsd so i would like to ask if your tutorial will help compress my css files or it will damage the website?

    Thank you

  20. John Louie
    Permalink to comment#

    I currently use this option create css.php into your assets and follow the code below

    and paste it to your header

    <link href="/css.php" rel="stylesheet" type="text/css"/>

    and its work…

    header("Content-type: text/css");// First of all send css header
    $css = array(// Array of css files
    foreach ($css as $css_file) {// Loop the css Array
           // Load the content of the css file
        $css_content = file_get_contents($css_file);
        echo $css_content;
         // print the css content
  21. Maher
    Permalink to comment#

    When i use the code like this :

    //ob_start ("ob_gzhandler");<br>
    header("Content-type: text/css; charset: UTF-8");<br>
    header("Cache-Control: must-revalidate");<br>
    $offset = 60 * 60 ;<br>
    $ExpStr = "Expires: " .<br>
    gmdate("D, d M Y H:i:s",<br>
    time() + $offset) . " GMT";<br>

    then i have a compress file, but the css file (style.php) does not work on my page! any suggestion ?

  22. Micha
    Permalink to comment#

    i personally like the way of getting the hash of the php file.

    like: style.php?r=md5 (file_get_contents(style.php)) to write it into the header.
    so if file is the same, and users have cached it, it doesn´t need to be loaded again.
    But if only 1 byte changed, every user has to redownload the file

  23. Iliya
    Permalink to comment#


    Very good idea!

  24. January

    Why do we have to compress css files with PHP?

    What is the reason?

    • Shubham Mathur
      Permalink to comment#

      Compressing CSS will result in lower loading time for your pages,
      For eg:
      a css file of 10kb would take more time and if same compressed css file is loaded it would definitely take less time.

  25. HenryNugraha
    Permalink to comment#

    bad practice for production.
    compress your css then save it instead of compress it everytime the page loads.
    how big is css anyway that you need to compress it, like, 999 Gigs?

Leave a Comment

Posting Code

We highly encourage you to post problematic HTML/CSS/JavaScript over on CodePen and include the link in your post. It's much easier to see, understand, and help with when you do that.

Markdown is supported, so you can write inline code like `<div>this</div>` or multiline blocks of code in in triple backtick fences like this:

  function example() {
    element.innerHTML = "<div>code</div>";

We have a pretty good* newsletter.