Optimising CSS
Warning: allowing an automated tool to alter the structure of your CSS can alter the meaning of your code. Please read and understand this section before using it.
Given this example style sheet:
div {
margin-top: 0;
margin-left: 5px;
margin-right: 5px;
margin-bottom: 1em;
}
li {
margin-top: 0;
margin-left: 5px;
margin-right: 5px;
margin-bottom: 1em;
}
the standard output of cssprepare is:
div{margin:0 5px 1em;}
li{margin:0 5px 1em;}
but, as you can see, the two selectors have exactly the same properties applied in these two rules. With optimisation turned on, cssprepare will output:
div,li{margin:0 5px 1em;}
In this case, the optimisation was beneficial. However, the cascade rules state that when selectors have equal specificity, the last rule wins. When optimising CSS, cssprepare can alter the structure of your style sheet so that rules are in different orders. Take the following example:
.warning { color: orange; }
.alert { color: red; }
If this CSS were to be applied to an element with both classes (eg. <p class='alert warning'>oh noes!</p>
), a user agent would style the text with the colour red.
When optimising CSS, cssprepare orders the output of selectors first by element, then by ID and then by class, all three types of which are sorted alphabetically. So those rules would be swapped around, causing the element to be styled orange instead. See the next section for methods of avoiding this in your style sheets.
That said, many style sheets will work just fine when optimised, especially when none of your selectors are ambiguous and rely on this aspect of the cascade.
Separate parts of the output
When optimising output, cssprepare first chunks the input into several blocks, and only optimises within each block. This is so that rule sets within a print @media
block are not mixed in with the rest of the style sheet, for example.
Any stylesheet that is included with @import
and all @media
blocks are chunked separately from the stylesheet they appear in. The appearance of a verbatim comment or block will cause the rule sets before and after to be treated as separate chunks, as will the chunking marker.
The following example would be treated by cssprepare as being three separate chunks, each optimised separately.
@media print {
body { background: #fff; } /* chunk #1 */
}
body { background: #ccc; } /* chunk #2 */
/* -- */
body { color: #000; } /* chunk #3 */
This will produce output of:
@media print{
body{background:#fff;}
}
body{background:#ccc;}
body{color:#000;}
Without the chunking marker, it would be treated as only two chunks, and output as:
@media print{
body{background:#fff;}
}
body{background:#ccc;color:#000;}
Suboptimal optimisation
CSS::Prepare tries very hard to optimise CSS to produce the biggest savings by combining properties and selectors. The exhaustive search, however, can take some time (eg. nearly 13 minutes for a 260k stylesheet with 14,000 declarations on a 2.4GHz Intel MacBook Pro), as it repeatedly compares the possible savings by combining different properties, rather than just combining the most obvious targets.
After a certain amount of time (by default, ten seconds) has elapsed whilst optimising a style sheet, CSS::Prepare will switch to a much faster, less exhaustive method for combining rules that does just combine the most obvious targets.