Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save starstuck/3248714 to your computer and use it in GitHub Desktop.
Save starstuck/3248714 to your computer and use it in GitHub Desktop.
Using Compass to generate normal and retina sprite maps
/**
* Setup images sprite having high resolution variant for retina displays.
*
* It will create class names for all available icons.
*
* This uses custom function to prefix selectors from array. To get it working you will need to include following snippet in your config.rb
*
* module Sass::Script::Functions
* def prefix_each(array, prefix)
* return Sass::Script::String.new array.to_a.map{|item| prefix.value + item.value}.join(", ")
* end
* declare :join_prefixed, :args => [:array, :string]
* end
*/
@mixin retina-sprite-item($sprite, $sprite-2x, $name) {
background-position: sprite-position($sprite, $name);
height: image-height(sprite-file($sprite, $name));
width: image-width(sprite-file($sprite, $name));
// Workaround for https://gist.github.com/2140082
@if (sprite-position($sprite, $name) != sprite-position($sprite-2x, $name)) {
@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3/2), (min-device-pixel-ratio: 1.5) {
background-position: 0 round(nth(sprite-position($sprite-2x, $name), 2) / 2);
height: round(image-height(sprite-file($sprite-2x, $name)) / 2);
width: round(image-width(sprite-file($sprite-2x, $name)) /2 );
}
}
}
@mixin retina-sprite($glob, $glob-2x, $prefix) {
$map: sprite-map($glob, $spacing: 1px);
$map-2x: sprite-map($glob-2x, $spacing: 2px);
$all-items: sprite-names($map);
#{prefix-each($all-items, ".#{$prefix}-")} {
background-image: sprite-url($map);
background-repeat: no-repeat;
display: block;
@media (-webkit-min-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3/2), (min-device-pixel-ratio: 1.5) {
background-image: sprite-url($map-2x);
@include background-size(ceil(image-width(sprite-path($map-2x)) / 2), auto);
}
}
@each $name in $all-items{
.#{$prefix}-#{$name} {
@include retina-sprite-item($map, $map-2x, #{$name});
}
}
}
@include retina-sprite("icons/*.png", "icons-2x/*.png", "icon");
@darren131
Copy link

Thank you for this. Pure genius!

@margold
Copy link

margold commented Nov 19, 2013

Thanks, that's incredibly useful!

This line doesn't work though:
@if (sprite-position($sprite, $name) != sprite-position($sprite-2x, $name))
because when the y-axis positions of 1x and 2x images in the sprite are equal, the background-position of the 2x will end up half that, because you're "scaling it down" in css terms:
(background-position: 0 round(nth(sprite-position($sprite-2x, $name), 2) / 2))

@rssems
Copy link

rssems commented Mar 12, 2014

What about multi sprite? 1 sprite for common, 1 sprite for homepage...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment