CSS Tools¶
The tools described here can be found in the → tdi.tools.css
module. The CSS tools mainly provide a minifier for now.
Minifying CSS¶
Minifying reduces the size of a document by removing redundant or irrelevant content. Typically this includes whitespace and comments. Some minifiers also try semantic reduction by collapsing rules, modifying color notations and so on.
TDI ships with the latest version of the rCSSmin minifier, which only removes spaces, comments and finishing semicolons – but does that very fast.
There are two use cases here:
- Minify style blocks within HTML templates during the loading phase
- Minify some standalone piece of CSS
The first case is handled by hooking the
→ tdi.tools.css.MinifyFilter
into the template loader. See the
filters documentation for a description how to do that.
For the second case there’s the → tdi.tools.css.minify
function:
from tdi.tools import css
print css.minify(u"""
fieldset p {
margin: 0.5em;
}
fieldset p span {
float: right;
display: inline-block;
font-size: 0.8em;
}
""".lstrip())
fieldset p{margin:0.5em}fieldset p span{float:right;display:inline-block;font-size:0.8em}
Masking Style Blocks¶
HTML has a long history of adding new elements all the time. Conceptually this is possible, because browsers simply ignore the tags of unknown elements and apply no semantics. That’s forward compatibility. Now if you place something inside these new elements, which is not HTML content, you get a backwards compatibility problem.
cdata and cleanup¶
Style elements (and script elements for that matter) suffer from this problem since they were invented. The first solution was to enclose them with comment markers, but add special rules for browsers to accept these markers as part of the content:
<style><!--
body {background-color: #fff; color: #000;}
--></style>
Then XHTML was invented. The XML parser cannot be tricked into such special rules. It would start throwing away the comment again, so people gave up backwards compliance and wrote:
<style><![CDATA[
body {background-color: #fff; color: #000;}
]]></style>
and then, to be compatible with HTML again:
<style>/*<![CDATA[*/
body {background-color: #fff; color: #000;}
/*]]>*/</style>
Then someone finally figured out [1] a mix of CDATA and comments completely compatible with all HTML/TagSoup parsers, and it looks like this:
[1] | http://lists.w3.org/Archives/Public/www-html/2002Apr/0053.html |
<style><!--/*--><![CDATA[/*><!--*/
body {background-color: #fff; color: #000;}
/*]]>*/--></style>
This is funny stuff, but you wouldn’t want to write it all the time. You should consider applying that, however, because browsers are typically not the only applications parsing your HTML.
The functions → css.cdata
and
→ css.cleanup
can do that for you. cdata()
takes a style block and encloses it in such an all-compatible
CDATA/comment-mix-container. cleanup()
does the reverse. It
looks for common containers (like the ones described above) and strips
them. In fact, the cdata()
function calls cleanup()
itself in order to avoid doubling itself:
from tdi.tools import css
print css.cdata("""
/*<![CDATA[*/
body {font-family: sans-serif;}
/*]]>*/
""".strip())
<!--/*--><![CDATA[/*><!--*/
body {font-family: sans-serif;}
/*]]>*/-->
The cdata()
function can be applied automatically to all style
blocks of a template by hooking the
→ tdi.tools.css.CDATAFilter
into the template loader. See
the filters documentation for a description how to do
that.