Using an Image sprite in a Media Query with Compass

I recently revisited some old Sass code and needed to fix it to compile with the latest version of Compass. After I cleaned out the CSS3Pie bits (yes it was that old) I ran into the dreaded You may not @extend an outer selector from within @media. error message.

It took me a bit of work to track down since the issue was several nestings deep in an @include stack but I finally traced it back to an image sprite call inside a media query. Apparently the version of Compass that was used before generated image sprites differently and didn’t use @extend.

I worked out a solution based largely on this gist and we’ll be exploring it today.

The Solution

When I use image sprites, I like to setup a helper _sprites.scss file.

[gist id=”e7d1f930ee351eb17123″ file=”_sprites.scss”]

This makes it easy to simply call show-icon-sprite('sprite-name') to get the image replacement, sprite details and width/height. The problem was that I had a button mixin that was using the show-icon-sprite mixin, but the button mixin was sometimes being called from within a media query.

I did some research and found the gist linked above which documented a replacement get-sprite mixin that would work within media queries and added that into my _sprites.scss file.

[gist id=”e7d1f930ee351eb17123″ file=”_sprites-with-media-query-extension.scss”]

Now I’ve got an alternative means of adding icon sprites, but I didn’t want to use it everywhere. I wanted to keep as much the same as I could and only change the bits that had to be changed so that Compass would run without error.

After I identified the issue with the button mixin, I added support for an additional parameter to specify if the mixin was being called from within a media query.

[gist id=”e7d1f930ee351eb17123″ file=”_buttons.scss”]

This let me use the “media-query-safe” image sprite mixin if the button mixin was being called from within a media query.

Now all that was left was to update the Sass where the button mixin was being called.

[gist id=”e7d1f930ee351eb17123″ file=”button-example.scss”]

I decided to use the map form of Sass arguments to avoid any kind of a “magic true” in the parameter list.

Now, any existing includes of the button mixin that aren’t in a media query will continue to work correctly and it is easy to update an include that is a media query.