Skip to content

Instantly share code, notes, and snippets.

@tovask
Last active September 19, 2017 12:43
Show Gist options
  • Save tovask/e40376b2ef09e86a3b6d3ce68989b529 to your computer and use it in GitHub Desktop.
Save tovask/e40376b2ef09e86a3b6d3ce68989b529 to your computer and use it in GitHub Desktop.
CSS minifier: additional functions to shorten some propertie's value
// https://github.com/matthiasmullie/minify
/**
* Merge same values to a shorter formula:
* 4 to 3, e.g.: "padding: 1px 2px 3px 2px" -> "padding: 1px 2px 3px"
* 3 to 2, e.g.: "padding: 1px 2px 1px" -> "padding: 1px 2px"
* 2 to 1, e.g.: "padding: 1px 1px" -> "padding: 1px"
* (if all the 4 values are the same, it will be shorten to 3, then to 2, then to 1. )
* Care about calc values too.
* Can only be applied to these properties: margin, padding, border-width and border-radius.
* (Note: other properties can't be shorten (as far as I know): e.g.: 'background-position:50px' is NOT equal to 'background-position:50px 50px', but equal to 'background-position:50px center'!)
* The border-radius property can be a bit more complex, the $before and $after params are to customize for this (see the shortenBorderRadius function).
*
* @param $css string the css code to minify
* @param $before string (optional) the pattern what precedes the values to be shorten
* @param $after string (optional) the pattern what follow the values to be shorten
*
* @return string the minified css code
*
*/
private function mergeValues($css, $before = 'margin\s*\:|padding\s*\:|border\-width\s*\:|border\-radius\s*\:', $after = '[;}]')
{
$value = '[^\s]+|calc\([^\)]+\)';
// 4 to 3:
$css = preg_replace('/('.$before.')\s*('.$value.')\s+('.$value.')\s+('.$value.')\s+\\3\s*(?='.$after.')/s', '\\1\\2 \\3 \\4', $css);
// 3 to 2:
$css = preg_replace('/('.$before.')\s*('.$value.')\s+('.$value.')\s+\\2\s*(?='.$after.')/s', '\\1\\2 \\3', $css);
// 2 to 1:
$css = preg_replace('/('.$before.')\s*('.$value.')\s+\\2\s*(?='.$after.')/s', '\\1\\2', $css);
return $css;
}
/**
* Handle border-radius special cases, cause by the '/'.
* Try to shorten the values before and after the '/' separately.
* Remove space from around the '/'.
* Merge the two side of the '/' if equals.
* e.g.: 'border-radius: 1px 2px 1px / 1px 2px 1px 2px'
* -> 'border-radius: 1px 2px'
*
* @param $css string the css code to minify
*
* @return string the minified css code
*
*/
private function shortenBorderRadius($css)
{
$css = $this->mergeValues($css, 'border\-radius\s*\:', '\/'); // merge before the '/'
$css = $this->mergeValues($css, 'border\-radius\s*\:[^;}\/]+\/', '[;}]'); // merge after the '/'
// remove space from around the '/'
$css = preg_replace('~
# find the target property
(border\-radius\s*\:)\s*
# values before the /
([^;}\/]+?)
# the /
\s*\/\s*
# values after the /
([^;}]+?)\s*
# end of property values
(?=[;}])
~sx',
'\\1\\2/\\3',$css);
// merge the two side of the '/', if equals
$css = preg_replace('~
# find the target property
(border\-radius\s*\:)
# values before the /
([^;}\/]+?)
# the /
\/
# values after the /, only match if equals what before that
\\2
# end of property values
(?=[;}])
~sx',
'\\1\\2',$css);
return $css;
}
/* minify first with the library */
$minified = $this->mergeValues($minified);
$minified = $this->shortenBorderRadius($minified);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment