CSS Compressor

CSS Compressor

Performance Optimierung mit CSS-Komprimierung & Workflow Optimierung

Die beste Performance Optimierung bietet die gzip-Komprimierung.
Wie viel Ersparnis das bringt kann mit PHP und dynamisch erzeugten CSS getestet werden

<?php
$gzip = true; // true oder false

if($gzip) {
    ob_start("ob_gzhandler");
}
?>

oder per .htaccess

<IfModule mod_deflate.c>
    <FilesMatch "\.(html|css|js|php|xml)$">
        SetOutputFilter DEFLATE
    </FilesMatch>
</IfModule>

Es gibt aber noch weitere kleine Schrauben die für die CSS-Komprimierung wichtig sind. Hier ein paar Beispiele.

Kommentare aus CSS entfernen
Für Frontend-Entwickler sind Kommentare im CSS ein wichtiger Bestandteil des Workflows. Jedoch sollen diese Informationen nicht Live eingesehen werden können.

<?php
$css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
?>

Doppelte Leerschritte, Tabulatoren, harte und weiche Returns entfernen

<?php
$css = preg_replace('/\s+/i',' ', $css);
?>

border, outline & opacity minifier

<?php
$css = str_replace("border:none", 'border:0', $css);
$css = str_replace("outline:none", 'outline:0', $css);
$css = str_replace("opacity:0.", 'opacity:.', $css);
?>

Leerschritte vor und nach :;,{}

<?php
$css = str_replace(": ", ':', $css);
$css = str_replace("; ", ';', $css);
$css = str_replace(" ;", ';', $css);
$css = str_replace(", ", ',', $css);
$css = str_replace(";;", ';', $css);
$css = str_replace("{ ", '{', $css);
$css = str_replace(" {", '{', $css);
$css = str_replace(" }", '}', $css);
$css = str_replace("} ", '}', $css);
?>

Einheiten minifier bei 0[Einheit]
margin: 0px; kann auch margin: 0; geschrieben werden

<?php
$css = str_replace(":0px", ':0', $css);
$css = str_replace(" 0px", ' 0', $css);
$css = str_replace(":0pt", ':0', $css);
$css = str_replace(" 0pt", ' 0', $css);
$css = str_replace(":0%", ':0', $css);
$css = str_replace(" 0%", ' 0', $css);
$css = str_replace(":0cm", ':0', $css);
$css = str_replace(" 0cm", ' 0', $css);
$css = str_replace(":0em", ':0', $css);
$css = str_replace(" 0em", ' 0', $css);
$css = str_replace(":0rem", ':0', $css);
$css = str_replace(" 0rem", ' 0', $css);
$css = str_replace(":0ex", ':0', $css);
$css = str_replace(" 0ex", ' 0', $css);
$css = str_replace(":0in", ':0', $css);
$css = str_replace(" 0in", ' 0', $css);
?>

background-position minifier

<?php
$css = str_replace('left top', '0 0', $css);
$css = str_replace('top left', '0 0', $css);
$css = str_replace('right top', '100% 0', $css);
$css = str_replace('right bottom', '100% 100%', $css);
$css = str_replace('right center', '100% 50%', $css);
$css = str_replace('left center', '0 50%', $css);
$css = str_replace('center center', '50% 50%', $css);
$css = str_replace('center bottom', '50% 100%', $css);
$css = str_replace('left bottom', '0 100%', $css);
?>

font-weight minifier
Auch die font-weight kann optimiert werden. So lässt sich bold mit 700 ersetzen und normal mit 400. So wird entweder ein oder drei Zeichen eingespart.

<?php
$css = str_replace('font-weight:bold;', 'font-weight:700;', $css);
$css = str_replace('font-weight:normal;', 'font-weight:400;', $css);
?>

color shorthand
Manche Farbwerte können vereinfacht werden… color: #ff6611; wird zu color: #f61;

/*
folgende Zeichen werden ausgeschlossen: "=" & "'="
    für z.B. filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFCC00', endColorstr='#F2B600');
    oder filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#FFCC00, endColorstr=#F2B600);
*/

$css = preg_replace('/([^\=\']#)([0-9a-f])\2([0-9a-f])\3([0-9a-f])\4/i', '\1\2\3\4',$css);

margin / padding shothand

<?php

// margin & padding shorthand Funktion

function shorthand_margin_padding($value) {
    $output_explode = explode(' ', $value);
    $values = count($output_explode);
    $output = $value;
    
    $important = '!important';
    
    if(($values == 4) || ($values == 5 && $output_explode[4] == $important)) {

        //BSP: 1px 2px 3px 2px => 1px 2px 3px
        if ($output_explode[0] != $output_explode[2] && $output_explode[1] == $output_explode[3]) {
            $output = $output_explode[0] . ' ' . $output_explode[1] . ' ' . $output_explode[2] . (($output_explode[4] == $important) ? ' ' . $important : '');
        }

        //BSP: 2px 4px 2px 4px => 2px 4px
        if ($output_explode[0] == $output_explode[2] && $output_explode[1] == $output_explode[3] && $output_explode[0] != $output_explode[1]) {
            $output = $output_explode[0] . ' ' . $output_explode[1] . (($output_explode[4] == $important) ? ' ' . $important : '');
        }
        
        //BSP: 4px 4px 4px 4px => 4px
        if (($output_explode[0] == $output_explode[1]) && ($output_explode[1] == $output_explode[2]) && ($output_explode[2] == $output_explode[3])) {
            $output = $output_explode[0] . (($output_explode[4] == $important) ? ' ' . $important : '');
        }

    }
    if ($values == 3 || ($values == 4 && $output_explode[3] == $important)) {
        //BSP: 3px 3px 3px => 3px
        if ($output_explode[0] == $output_explode[1] && $output_explode[0] == $output_explode[2]) {
            $output = $output_explode[0] . (($output_explode[3] == $important) ? ' ' . $important : '');
        }

        //BSP: 3px 0 3px => 3px 0
        if ($output_explode[0] == $output_explode[2] && $output_explode[0] != $output_explode[1]) {
            $output = $output_explode[0] . ' ' . $output_explode[1] . (($output_explode[3] == $important) ? ' ' . $important : '');
        }

    } 
    if ($values == 2 || ($values == 3 && $output_explode[2] == $important)) {
        //BSP: 3px 3px => 3px
        if ($output_explode[0] == $output_explode[1]) {
            $output = $output_explode[0] . (($output_explode[2] == $important) ? ' ' . $important : '');
        }

    }
    return $output;
}


// margin & pading shorthand Aufruf
$css = preg_replace("/(margin|padding):(((-|)(\d|\.|)+(px|em|rem|%|pt|cm|auto|in|ex|!important)?( +?)?){1,5});?/e","'\\1:' . shorthand_margin_padding('\\2').';'", $css);

?>

Semikolon in brackets minifier
Das letzte Semikolon in der geschweiften Klammer kann entfernt werden.

<?php
$css = str_replace(";}", '}', $css);
?>

Globale CSS Variablen
Platzhalter im CSS können durch definierte Eigenschaften ersetzt werden.

<?php
$css = str_replace("font-family:_FONT_;", 'font-family:opensans,Arial,Helvetica,sans-serif;', $css);
$css = str_replace("font-family:_FONTBOLD_;", 'font-family:opensansbold,Arial,Helvetica,sans-serif;', $css);

$css = str_replace("_COLOR_", '#0097dc', $css);
?>

Einbetten von Bildern und Schriften ins CSS mit base64

<?php

$cssembed = true; // true oder false

function data_uri($file) {

    global $cssembed;

    if($cssembed) {

        $first = "/^\//";
        $file = preg_replace($first, '../', $file); // Anpassen je nachdem wo die Dateien liegen

        $contents = file_get_contents($file);
        $base64   = base64_encode($contents);

        if(strpos($file, '.jpg')) {
            $mime = 'image/jpeg';
        } else if(strpos($file, '.gif')) {
            $mime = 'image/gif';
        } else if(strpos($file, '.svg')) {
            $mime = 'image/svg+xml';
        } else if(strpos($file, '.png')) {
            $mime = 'image/png';
        } else if(strpos($file, '.woff')) {
            $mime = 'application/font-woff;charset=utf-8';
        } else {
            return false;
        }

        return ('data:' . $mime . ';base64,' . $base64);

    } else {
        return $file;
    }

}

// Aufruf z.B. hier mit: #logo {background: url(_URI[/i/logo.png]_);}
$css = preg_replace('/(_URI\[)(.*?)\]_?/e',"data_uri('\\2')", $css);
?>

Media Queries herausfiltern und am Ende der CSS-Datei ausgeben

<?php
$mediaqueries1 = '';
function mediaqueries1($getinput) {
    global $mediaqueries1;
    $mediaqueries1 .= $getinput;
}

$mediaqueries2 = '';
function mediaqueries2($getinput) {
    global $mediaqueries2;
    $mediaqueries2 .= $getinput;
}

/*
Dieser Eintrag aus dem Beispiel oben wird benötigt
$css = preg_replace('/\s+/i',' ', $css);
*/

$css = preg_replace('/(_mq1_)(.*?)(_mqend_)/e',"mediaqueries1('\\2')", $css);
$css = preg_replace('/(_mq2_)(.*?)(_mqend_)/e',"mediaqueries2('\\2')", $css);

$css = $css . (($mediaqueries1 != '') ? '@media screen and (min-width: 320px) {'.$mediaqueries1.'}' : '' ) . (($mediaqueries2 != '') ? '@media screen and (min-width: 480px) {'.$mediaqueries2.'}' : '' );

/*
Beispiel in dynamischer CSS-Datei:

_mq1_
.mediaqueries {background: green;}
_mqend_

.mediaqueries2 {background: blue;}

_mq2_
.mediaqueries {background: red;}
_mqend_

Ausgabe:

.mediaqueries2 {background: blue;}

@media screen and (min-width: 320px) {
    .mediaqueries {background: green;}
}

@media screen and (min-width: 480px) {
    .mediaqueries {background: red;}
}
*/
?>

Für alle diese Optimierungen gibt es auch schon fertige Tools wie z.B. CodeKit das auch z.B. LESS & SASS unterstützt. Da auch mal Fehler auftreten können, sollte in jedem Fall ein Diff-Programm für jede CSS-Anpassung zum Einsatz kommen.

Impressum