31 Jan 2014

Regular and Retina Sprites with Compass

So you use compass to build sprites, but now you want everything to have 2x graphics? This mixin should get you up and running.

Bear in mind that you should make sure all images have even dimensions. If you have a 115x115px image in the retina size, you should bump it up to 116x116px and have a regular sized image of 58x58px. This is a slight modification of this gist.

 1 $sprite: sprite-map("sprite-sprite/*.png");
 2 $sprite-retina: sprite-map("sprite-sprite-retina/*.png");
 3 
 4 @mixin sprite-background($name) {
 5   $width: image-width(sprite-file($sprite, $name));
 6   $height: image-height(sprite-file($sprite, $name));
 7 
 8   background-image: sprite-url($sprite);
 9   background-position: sprite-position($sprite, $name);
10   background-repeat: no-repeat;
11   width: $width;
12   height: $height;
13 
14   $background-width-size: image-width(sprite-path($sprite));
15 
16   @media (-webkit-min-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 3/2), (min-device-pixel-ratio: 2) {
17     // Workaround for https://gist.github.com/2140082
18     @if (sprite-position($sprite, $name) != sprite-position($sprite-retina, $name)) {
19       $ypos: round(nth(sprite-position($sprite-retina, $name), 2) / 2);
20       background-position: 0 $ypos;
21     }
22 
23     @include background-size($background-width-size auto);
24     background-image: sprite-url($sprite-retina);
25   }
26 }

Usage

Just use the filename without the extension (all files should be .png extension). You'll need to give your element display: block; or display: inline-block; in order for it to work. You could add this to the mixin if you wanted.

1 .someclass {
2   @include sprite-background("file");
3 }

Edit: I should have included the original source for this which is this gist by thulstrup. This solution takes the fix proposed by rstacruz in order to avoid hard coding the sprite width manually.

comments powered by Disqus