Thursday, January 27, 2011

YUI Compressor breaks CSS3 Media Query Syntax

If you use the CSS3 Media Query Syntax for something like this:

@media screen and (max-device-width: 480px) {
body {font-size: 18px;}

You will find that when you compress this with YUI Compressor (as is done when packaging your assets with Jammit), that the output breaks this syntax. YUI Compressor removes the whitespace between the "and" and the opening parenthesis, which does not conform to the CSS3 standard, and renders those styles unusable in most browsers (tested in Chrome and Safari, read about others hitting this in Firefox).

There's a YUI Compressor bug filed here that covers this:

My Workaround

I am invoking YUI Compressor via an asset-packager called Jammit. In a blog post yesterday, I noted some problems I encountered with Jammit not handling duplicate @charset directives generated by Sass/Compass, and outlined a quick hack workaround I used to deal with it.

Today, encountering this @media-related bug leads to an additional workaround I had to add to that. So, I figured I'd share a bit of my resulting rake task that combines all of these.

  • Use compass to compile my Sass to CSS without compressing it (this is important)

  • Use sed to remove all @charset directives (dangerous, but I know I don't need them in this case). Take care to make sure the differences in how the -i parameter to sed works between OS X and Linux.

  • Use jammit to package up everything.

  • For each permutation (e.g.: normal, datauri) CSS package jammit generated, use sed to add the missing space back in to offending @media directives.

  • For each of those CSS files we sed-edited, re-gzip them. (Jammit made gzipped versions originally, but we have to regenerate them since we changed the contents.)

Here's the final rake task:

No comments: