Created
June 14, 2013 13:34
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @author Dan Bettles <[email protected]> | |
* | |
* @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 <[email protected]> | |
*/ | |
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