Skip to content

Instantly share code, notes, and snippets.

@manastungare
Created May 7, 2012 00:23
Show Gist options
  • Save manastungare/2625128 to your computer and use it in GitHub Desktop.
Save manastungare/2625128 to your computer and use it in GitHub Desktop.
On-the-fly CSS Compression
<?php
/**
* On-the-fly CSS Compression
* Copyright (c) 2009 and onwards, Manas Tungare.
* Creative Commons Attribution, Share-Alike.
*
* In order to minimize the number and size of HTTP requests for CSS content,
* this script combines multiple CSS files into a single file and compresses
* it on-the-fly.
*
* To use this in your HTML, link to it in the usual way:
* <link rel="stylesheet" type="text/css" media="screen, print, projection" href="/css/compressed.css.php" />
*/
/* Add your CSS files to this array (THESE ARE ONLY EXAMPLES) */
$cssFiles = array(
"ads.css",
"formatting.css",
"pagesections.css",
"print.css",
"screen.css",
"sidebar.css"
);
/**
* Ideally, you wouldn't need to change any code beyond this point.
*/
$buffer = "";
foreach ($cssFiles as $cssFile) {
$buffer .= file_get_contents($cssFile);
}
// Remove comments
$buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
// Remove space after colons
$buffer = str_replace(': ', ':', $buffer);
// Remove whitespace
$buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer);
// Enable GZip encoding.
ob_start("ob_gzhandler");
// Enable caching
header('Cache-Control: public');
// Expire in one day
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 86400) . ' GMT');
// Set the correct MIME type, because Apache won't set it for us
header("Content-type: text/css");
// Write everything out
echo($buffer);
?>
@impishj
Copy link

impishj commented Nov 5, 2012

Made a little OSX front end for this because I wanted a convenient way to strip css comments out of my files. https://github.com/impishj/simple-osx-css-compressor

Thanks for the script

@barnettjw
Copy link

Stripping out all spaces seems to break CSS descendant selectors, instead replace 2 or more spaces, with a single space.

Change this:

$buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer);

To this:

$buffer = str_replace(array("\r\n", "\r", "\n", "\t"), '', $buffer);
$buffer = ereg_replace(" {2,}", ' ',$buffer);

@maxbmx
Copy link

maxbmx commented Aug 3, 2013

Why you don't use trim(); ?

@ivansky
Copy link

ivansky commented Aug 12, 2014

$buffer = preg_replace('/[\t\r\n]+/', '', $buffer);
$buffer = preg_replace('/[\s]{2,}/', ' ', $buffer);
$buffer = str_replace(': ', ':', $buffer);

@brentonstrine
Copy link

I forked this to fix an issue it had. It would break space-separated values when the developer has used more than one space to separate the values. Pertinent code is here:

// Remove whitespace
$buffer = str_replace(array("\r\n", "\r", "\n", "\t"), '', $buffer);

// Collapse adjacent spaces into a single space
$buffer = ereg_replace(" {2,}", ' ',$buffer);

// Remove spaces that might still be left where we know they aren't needed
$buffer = str_replace(array('} '), '}', $buffer);
$buffer = str_replace(array('{ '), '{', $buffer);
$buffer = str_replace(array('; '), ';', $buffer);
$buffer = str_replace(array(', '), ',', $buffer);
$buffer = str_replace(array(' }'), '}', $buffer);
$buffer = str_replace(array(' {'), '{', $buffer);
$buffer = str_replace(array(' ;'), ';', $buffer);
$buffer = str_replace(array(' ,'), ',', $buffer);

@cyberwani
Copy link

@manas, if compressing multiple stylesheets from different locations. And, some stylesheets contains links to fonts and images. How to handle this?

@bfintal
Copy link

bfintal commented Aug 1, 2015

Adding to this, you can shorten hex colors like #aabbcc to #abc with

$buffer = preg_replace("/#([0-9a-fA-F])\\1([0-9a-fA-F])\\2([0-9a-fA-F])\\3/", "#$1$2$3", $buffer);

@bfintal
Copy link

bfintal commented Aug 2, 2015

I've combined all the space removal str_replace by @brentonstrine and added a bit more to include >, ~ and : to the detected characters

// Remove spaces that might still be left where we know they aren't needed
$buffer = preg_replace( "/\s*([\{\}>~:;,])\s*/", "$1", $buffer );
// Remove last semi-colon in a block
$buffer = preg_replace( "/;\}/", "}", $buffer );

@bfintal
Copy link

bfintal commented Aug 2, 2015

Might be in the extremes:

// Convert CSS content icons to glyphs
function css_content_hex_to_glyph( $matches ) {
    return html_entity_decode( '&#x' . trim( $matches[1], '\\' ) . ';', 0, 'UTF-8' );
}
$buffer = preg_replace_callback( "/(?<=content:[\"'])(\\\[0-9a-fA-F]+)/", 'css_content_hex_to_glyph', $buffer );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment