=head1 Optimising CSS

=for text
When passed the C<-o> (C<--optimise>) option, cssprepare will restructure
your CSS to save as much bandwidth as possible before outputting it.

B<Warning:> allowing an automated tool to alter the structure of your CSS
can B<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. C<< 
<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. 

=head2 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 C<@media> block are not mixed in with the rest of the style sheet, for
example. 

Any stylesheet that is included with C<@import> and all C<@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;}

=head2 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.