Automagic Retina-Ready Sprites with Compass and SASS

Sprites are a classic trick for speeding up a web page load time. Why make a request for dozens of dinky images when you can grab one sprite sheet and position it accordingly with CSS? Traditionally though, making sprites by hand is a tedious pain requiring Photoshop, pixel counting, and copying/pasting. Ew. And nowadays with all these higher resolution “retina” displays floating around, that means double the spriting is required.

Luckily for us Ruby users, the Compass CSS Framework gives us the ability to automatically generate sprite sheets in our Sprockets asset pipelines. But how can we handle retina versions without? Some Googling yielded this gist which I SASS-ized and modified slightly to handle retina background size calculations and devices with pixel ratios of 1.5. First, make sure compass and sass (or their -rails versions) are in your Gemfile, dump all your normal sprited images in one folder and @2x versions in another.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@import compass/utilities/sprites
@import compass/css3/background-size

$sprites: sprite-map("sprites/*.png")
$sprites2x: sprite-map("sprites2x/*.png")

=sprite-background($name)
  background-repeat: no-repeat
  display: block
  background-image: sprite-url($sprites)
  background-position: sprite-position($sprites, $name)
  height: image-height(sprite-file($sprites, $name))
  width: image-width(sprite-file($sprites, $name))

  @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($sprites2x)
    background-position: 0 round(nth(sprite-position($sprites2x, $name), 2) / 2)
    height: round(image-height(sprite-file($sprites2x, $name)) / 2)
    width: round(image-width(sprite-file($sprites2x, $name)) /2 )

    /* treat the @2x retina sprite sheet as 50% wide for double resolution upon display
    +background-size(ceil(image-width(sprite-path($sprites2x)) / 2) auto)

/* example declaration
.help-icon
  +sprite-background(help-icon)

Just like that – sprites are compiled, dimensions and positioning are calculated with Ruby, and its all dumped to a CSS file with media queries for denser displays. Photoshop can stay closed and reserved for more exciting things like meme-ing images.

Comments