Skip to content

Instantly share code, notes, and snippets.

@nickawalsh
Last active October 7, 2021 09:38
Show Gist options
  • Star 98 You must be signed in to star a gist
  • Fork 19 You must be signed in to fork a gist
  • Save nickawalsh/4232779 to your computer and use it in GitHub Desktop.
Save nickawalsh/4232779 to your computer and use it in GitHub Desktop.
Auto Hi-res Sprites
@import compass
$icons: sprite-map("icons/*.png")
$icons-hd: sprite-map("icons-hd/*.png")
i
background: $icons
display: inline-block
@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi)
background: $icons-hd
+background-size(image-width(sprite-path($icons)) auto)
@each $icon in sprite_names($icons)
.icn-#{$icon}
+sprite-dimensions($icons, $icon)
background-position: sprite-position($icons, $icon)
@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi)
$offset: nth(sprite-position($icons-hd, $icon), 2) / 2
background-position: 0 $offset
@nickawalsh
Copy link
Author

Grabs all png files from images/icons and creates a sprite. Each file has a class of icn-filename created, with the appropriate dimensions and background position. At the same time, a sprite is compiled from double-resolution images (using the same file names, in images/icons-hd) and set with the appropriate media query.

Needs a bit of adjustment if you plan on adding $spacing to the generated sprite or use a layout other than vertical.

@nickawalsh
Copy link
Author

You'll likely want to include some sort of image replacement technique on i, for places where fallback text is appropriate.

@Miggz
Copy link

Miggz commented Dec 28, 2012

This is awesome. One issue that I see is when zooming in FF or IE. once I zoom in far enough, the image switches to the hd image, but he background-size no longer seems to work. Not sure if this is a bug, or how to compensate for this, but I'm looking at it right now.

@Miggz
Copy link

Miggz commented Dec 28, 2012

So I came up with two ways to remedy this. One is to set the +background-size inside of the @each. The downside to this will write a lot of extra css. Extra statement for every icon.

The alternative I used was to call the background on i with an !important and this will force it everywhere.

example: background-size: image-width(sprite-path($sprites)), auto !important;

This is not perfect, but in this situation I feel like the !important is the lesser of evils.

Thanks again for this great snippet.

@nickawalsh
Copy link
Author

Huh, that's really interesting - thanks for posting your findings (and sorry I missed them the first time around). I'll let you know if we stumble across a way to fix that without the extra duplication.

@nickawalsh
Copy link
Author

Important fix for retina icon serving - the background-size declaration needs to come after the background declaration.

@dariye
Copy link

dariye commented May 14, 2013

Thanks nick. I just wrapped up Assembling Sass 2

@AlexRule7
Copy link

$icons    : sprite-map("icons/*.png", $layout: smart)
$icons-hd : sprite-map("icons-hd/*.png")

$layout: smart — will save some kb for you. But use it only with non-retina sprite.

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