To preprocess the CSS you call renderCSS($cssText) Without preprocessing: #navbar { border: 1px solid black; } #navbar h2 { background-color: black; color: white; } #navbar li { float: left; width: 100px; } With preprocessing (this may not syntax highlight correctly): #navbar { border: 1px solid black; //Applies to h2s within the navbar h2 { background-color: black; color: white; } li { float: left; width: 100px; } } And here's the php Code: /** * Renders a snippet of CSS * * @param string $cssText * @return string */ function renderCSS($cssText) { $data = preg_replace('/(\/\/.*\n)/',"",$cssText); // remove single line comments, like this, from // to \\n $data = preg_replace('/(\t|\r|\n)/',"",$data); // remove new lines \\n, tabs and \\r $data = preg_replace('/(\/\*[^*]*\*\/)/','',$data); // remove multi-line comments /* */ $data = preg_replace('/(\/\*[^\/]*\*\/)/','',$data); // remove multi-line comments /* */ $data = preg_replace('/(\s+)/', ' ',$data); // replace multi spaces with singles $data = fixNesting($data); $data = preg_replace('/[^}{]+{\s?}/', '', $data); //Remove empty rules $data = preg_replace('/\s*{\s*/', "{", $data); $data = preg_replace('/\s*}\s*/', "}", $data); $data = preg_replace('/}/', "}\n", $data); return $data; } // Helper callback function for fixNesting (below) function fixNesting_buildSelector($outer, $inner) { $outerPieces = split(",", $outer); if (trim($inner) == "IEHACK") { foreach ($outerPieces as $o) { $resultPieces[] = "* html " . $o; } } else { $innerPieces = split(",", $inner); $resultPieces = array(); foreach ($outerPieces as $o) { foreach ($innerPieces as $i) { $resultPieces[] = $o . " " . $i; } } } return join(",", $resultPieces); } // Helper callback function for fixNesting (below) function fixNesting_selector($selectors, $depth) { $newSelector = $selectors[0]; for($j = 1;$j<$depth; $j++) { $newSelector = fixNesting_buildSelector($newSelector, $selectors[$j]); } return $newSelector; } function fixNesting($cssText) { $result = array(); $pieces = split("{", $cssText); $selectorStackIndex = 0; $selectorStack = array(); $currentPieceIndex = 0; for ($i = 0; $i 0) { $result[] = substr($piece, 0, $closeBracketPos); } $result[] = "}"; $selectorStackIndex--; if ($selectorStackIndex > 0 ) { $result[] = fixNesting_selector($selectorStack, $selectorStackIndex); $result[] = "{"; } $piece = substr($piece, $closeBracketPos+1); } if (trim($piece) == '') { continue; } // Inner Rule $endOfLastProperty = strrpos($piece, ";"); if ($endOfLastProperty !== false) { $result[] = substr($piece, 0, $endOfLastProperty+1); $piece = substr($piece, $endOfLastProperty+1); } if ($selectorStackIndex > 0) { $result[] = "}"; } // Whole piece is the selector $selector = $piece; $selectorStack[$selectorStackIndex++] = $selector; $result[] = fixNesting_selector($selectorStack, $selectorStackIndex); $result[] = '{'; } $result = join($result); return $result; }