Skip to content

Instantly share code, notes, and snippets.

@danbettles
Created June 14, 2013 13:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danbettles/5781842 to your computer and use it in GitHub Desktop.
Save danbettles/5781842 to your computer and use it in GitHub Desktop.
Basic, but very effective, CSS minifier for CodeIgniter - or anything else if you extract the behaviour.
<?php
/**
* @author Dan Bettles <danbettles@yahoo.co.uk>
*
* @license http://creativecommons.org/licenses/by-nc-sa/2.0/uk/ by-nc-sa
*/
if ( ! defined('BASEPATH'))
{
exit('No direct script access allowed');
}
/**
* Minifies CSS
*
* @author Dan Bettles <danbettles@yahoo.co.uk>
*/
class Css_minifier {
public function minify($css)
{
$minified_css = $css;
$minified_css = $this->_normalize_whitespace($minified_css);
$minified_css = $this->_remove_comments($minified_css);
$minified_css = $this->_remove_unneeded_whitespace($minified_css);
$minified_css = $this->_remove_units_from_zeroes($minified_css);
$minified_css = $this->_collapse_hex_colours($minified_css);
$pct_reduction = round((strlen($minified_css) / strlen($css)) * 100);
$message = "/*{$pct_reduction}%*/";
return $message . PHP_EOL . $minified_css;
}
private function _normalize_whitespace($css)
{
//Normalize newlines
$css = preg_replace('/\r\n|\r|\n/', PHP_EOL, $css);
//Normalize horizontal whitespace
$css = preg_replace('/[ \t]/', ' ', $css);
return $css;
}
private function _remove_comments($css)
{
return preg_replace('{\/\*(?:.*?)\*\/}s', '', $css);
}
private function _remove_unneeded_whitespace($css)
{
$css = trim($css);
//Replace multiple, contiguous occurrences of a whitespace character with just the one
$css = preg_replace('/(\s){2,}/s', '$1', $css);
//Remove leading and trailing whitespace from lines
$css = preg_replace('/^[ ]+|[ ]+$/m', '', $css);
//Remove horizontal whitespace around commas, colons, semi-colons, and braces
$css = preg_replace('/[ ]*([,:;\{\}])[ ]*/', '$1', $css);
return $css;
}
private function _remove_units_from_zeroes($css)
{
return preg_replace('/\b0(?:(?:px|em)\b|%)/i', '0', $css);
}
private function _collapse_hex_colours($css)
{
$pattern_hex_byte = '[0-9a-fA-F]{2}';
if (preg_match_all("/(#)({$pattern_hex_byte})({$pattern_hex_byte})({$pattern_hex_byte})/", $css, $matches))
{
$replacement_colours = array();
foreach (array_keys($matches[0]) as $colour_no)
{
$original_colour = $matches[0][$colour_no];
//Proceed to the next colour if we've already replaced this one
if (array_key_exists($original_colour, $replacement_colours))
{
continue;
}
$collapsed_colour = $matches[1][$colour_no]; /*(Starts with the prefix)*/
foreach (array(2, 3, 4) as $byte_no)
{
$byte = $matches[$byte_no][$colour_no];
//Proceed to the next colour if the digits comprising the byte aren't the same as each other
if ($byte[0] !== $byte[1])
{
continue 2;
}
$collapsed_colour .= $byte[0];
}
//Replace the original colour throughout the CSS
$css = str_replace($original_colour, $collapsed_colour, $css);
//Make a note of the colour we just replaced
$replacement_colours[$original_colour] = $collapsed_colour;
}
}
return $css;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment