Skip to content

Instantly share code, notes, and snippets.

@thulstrup
Created March 20, 2012 19:18
Show Gist options
  • Save thulstrup/2140082 to your computer and use it in GitHub Desktop.
Save thulstrup/2140082 to your computer and use it in GitHub Desktop.
Using Compass to generate normal and retina sprite maps
$sprites: sprite-map("sprites/*.png");
$sprites-retina: sprite-map("sprites-retina/*.png");
@mixin sprite-background($name) {
background-image: sprite-url($sprites);
background-position: sprite-position($sprites, $name);
background-repeat: no-repeat;
display: block;
height: image-height(sprite-file($sprites, $name));
width: image-width(sprite-file($sprites, $name));
@media (-webkit-min-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 3/2), (min-device-pixel-ratio: 2) {
// Workaround for https://gist.github.com/2140082
@if (sprite-position($sprites, $name) != sprite-position($sprites-retina, $name)) {
$ypos: round(nth(sprite-position($sprites-retina, $name), 2) / 2);
background-position: 0 $ypos;
}
// Hard coded width of the normal sprite image. There must be a smarter way to do this.
@include background-size(444px auto);
background-image: sprite-url($sprites-retina);
}
}
// Usage.
.mail-icon {
@include sprite-background(mail);
}
@AdamBrodzinski
Copy link

@tegola , not sure it this is related but you may want to checkout this issue.

@nathansh
Copy link

I've had issues with the retina sprite when using smart layout. I tried to use smart layouts as follows:

$sprites-retina: sprite-map("double/*.png", $layout: smart);

This resulted in two identical sprite images as expected, but SASS wasn't calculating the distances properly at all.

@yahreen
Copy link

yahreen commented Apr 8, 2013

I am having issues with $layout: smartas well. Anyone have a fix?

@jessicaldale
Copy link

Anyone get '$layout: smart' working? Also, is anyone using this with images of varying sizes/dimensions? I want to create a sprite that contains all of my site's ui elements, but they aren't all square shaped.

@eprothro
Copy link

eprothro commented Nov 4, 2013

We prefer using the compass helpers for sprite map and style class generation. This is a bit more future proof than manually setting background-size as well as less labor intensive than generating the style classes manually:

Compass Retina Spriting

@heidmotron
Copy link

@thulstrup Can you include an open source license in this gist?

@brewster1134
Copy link

here is my take on retina sprites. i wanted a way to use it within the @media directive as well...

https://gist.github.com/brewster1134/13162e2cb0220e87b017

I would love some feedback...

@mbilalsiddique1
Copy link

Here is my try to make it little short and for best practice. I wanted to use background-image property for once instead of using it in every class to minimise my code. I make this
https://github.com/mbilalsiddique1/Sass-Mixins

@import "compass/utilities/sprites";         // Include compass sprite helpers
@import "compass/css3/background-size";      // Include helper to calc background size

// General Sprite Defaults
// You can override them before you import this file.
$icon-sprite-base-class: ".icon-sprite" !default;
$icon-sprite-dimensions: false !default;
$icon-spacing: 10px !default;
$icon-position: 0% !default;
$icon-repeat: no-repeat !default;

$icon-sprites: sprite-map("sprites/*.png", $spacing: $icon-spacing, $repeat: $icon-repeat, $position: $icon-position);
$icon-sprites-retina: sprite-map("sprites-retina/*.png", $spacing: $icon-spacing * 2, $repeat: $icon-repeat, $position: $icon-position);

// All sprites should extend this class
// The icon-sprite mixin will do so for you.
#{$icon-sprite-base-class} {
  background: $icon-sprites $icon-repeat;
}

@media (-webkit-min-device-pixel-ratio: 1.5), (min--moz-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3 / 2), (min-device-pixel-ratio: 1.5), (min-resolution: 1.5dppx) {
  #{$icon-sprite-base-class} {
    background: $icon-sprites-retina $icon-repeat;
    @include background-size(ceil(image-width(sprite-path($icon-sprites-retina)) / 2) auto);
  }
}

// Extends the sprite base class and set the background position for the desired sprite.
// It will also apply the image dimensions if $dimensions is true.
@mixin icon-sprite($name, $dimensions: $icon-sprite-dimensions, $offset-x: 0, $offset-y: 0) {
  @extend #{$icon-sprite-base-class};
  @include sprite($icon-sprites, $name, $dimensions, $offset-x, $offset-y)
}

// Example Usage.
.icon-analytics {
    @include icon-sprite(main-sprite);
}

@tomasdev
Copy link

My smaller contribution: https://gist.github.com/tomasdev/56bc62e86ab0700f8298 works right out of the box if you're planning to save only the biggest assets and not the pixelated (non-retina) ones.

@mgarabedian
Copy link

@mbilalsiddique1 - thanks for this bit above. Working well for my usage thus far. Maybe i missed it, but any way to have the css for all icons in the folder automatically render with their unique file names as classes, instead of defining each one again ( as you show in your example ) ?

// Example Usage. .icon-analytics { @include icon-sprite(main-sprite); }

@mgarabedian
Copy link

I believe i figured it out how to declare all the sprites in the map. Works well on top of whats above.

$sprite-names: sprite_names($icon-sprites);
@each $sprite in $sprite-names {
    .icon-#{$sprite} {
      @include icon-sprite($sprite, true);
    }
} 

@julkue
Copy link

julkue commented Jul 9, 2015

How to combine this mixin to get the image height of the sprite?

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