@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: http://yuilibrary.com/projects/yuicompressor/ticket/2528053
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:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace :assets do | |
task :rebuild do | |
# Config the base names of all the jammit CSS packages you have defined | |
# in assets.yml. Could probably parse assets.yml to get this if | |
# we wanted to. | |
packages = ['common'] | |
# This is because on OS X, you have to put an explicit empty string to the | |
# required extension argument with the -i parameter, but on Linux you | |
# do not. | |
in_place_option = "-i" | |
if `uname` =~ /darwin/i | |
in_place_option = '-i ""' | |
end | |
Dir.chdir(RAILS_ROOT) do | |
sh("compass compile --force") | |
# This is a workaround for this jammit bug: | |
# https://github.com/documentcloud/jammit/issues/#issue/120 | |
# | |
sh("sed #{in_place_option} -e \"s/^@charset.*$//g\" public/stylesheets/*.css") | |
sh("jammit --force") | |
# This is a workaround for this YuiCompressor bug: | |
# http://yuilibrary.com/projects/yuicompressor/ticket/2528053 | |
# | |
Dir.chdir("public/assets") do | |
packages.each do |package| | |
Dir.glob("#{package}*.css").each do |file| | |
sh("sed #{in_place_option} -e \"s/@media \\([^[:space:]]*\\) and(/@media \\1 and (/g\" #{file}") | |
sh("gzip --best --stdout #{file} > #{file}.gz") | |
end | |
end | |
end | |
end | |
end | |
end |