Compass and Slicy Will Make Your Sprites and Write Your CSS

Making sprites sucks. They’re incredibly useful for web development since they keep assets minimal and HTTP requests (and thus loading times) low, but they are a huge time sink: somebody has to Tetris together a bunch of tiny images into one file so that they fit in as little space as possible, then figure out all the dimensions and coordinates of every little icon, make up class names for every single one, then write a bunch of verbose CSS so you can actually use the individual icons in the sprite. What a pain.

I used to argue with our designers about who should build sprites. But even if I escaped the burden of creating one, writing the related CSS was painful too. Adding a new icon to a sprite was regularly a source of mental anguish. Our main sprites can easily have over 50 different images and icons in it — when you run a huge website like the Behance Network or a complex web application like Action Method, it’s not unusual to be dealing with that many different icons. So we changed our spriting process completely.

The red arrows are pointing to icons used in AMO. This is only a fraction of the icons in the sprite.

Now, we let two applications do the hard work for us: Slicy (previously known as Layer Cake), a Mac application by MacRabbit that automatically slices and exports your Photoshop layers based on their names, and Compass, a popular Sass framework with a built-in sprite generator.

Our work flow is brilliantly simple and quick now. Our designers name their layers as they go along, then simply drop their PSD into Slicy, which generates individual images based on the layer names. The generated images are then handed off to the developer, and the designer’s contribution to the sprite is now completely done. (Seriously.)

The layers with .png appended so Slicy knows what to export.

For the developer, the process is just as simple thanks to Compass. All it takes is a little bit of magic: in a Sass file, tell Compass where your individual images are, set a couple customization variables, save your code and let Compass stitch all of your images into one sprite. Along with your new sprite, Compass generates the CSS for every individual image’s class name, dimensions and coordinates. The only thing left is to put class names in your markup. I kid you not. It’s that easy.

The individual images, the compiled sprite, and the generated CSS.

Here’s the technical breakdown for getting Compass to generate a sprite:

1. Our file structure looks like this:

config.rb
css/
  sprites.css
images/
  sprite/
    dashed-border-add-file.png
    icon-actionstep-focus.png
    icon-actionstep-overdue.png
    icon-actionstep-today.png
    icon-activity-accept-selected.png
    ... all the rest of the individual images Slicy made for us ...
sass/
  sprites.scss



2. The config.rb for our Compass project designates where our Sass, CSS and images are stored. We also have a hook for automatically renaming and moving sprites when they’re done being compiled.

http_path = "/" # not used in this exercise
css_dir = "css"
sass_dir = "sass"
images_dir = "images"
javascripts_dir = "javascripts" # not used in this exercise

output_style = :expanded
sass_options = {:unix_newlines=>true}
line_comments = false
preferred_syntax = :scss

# Rename sprites to remove the Compass-generated hash and move it up 1 directory
on_sprite_saved do |filename|
  if File.exists?(filename)
    FileUtils.mv filename, filename.gsub(%r{-s[a-z0-9]{10}\.png$}, '.png').gsub('images/../images/', '')
  end
end



3. In sprites.scss, we set some magic variables and call some magic functions – they’re magic because their existence is based on the name of the folder where your images are stored. Our images are stored in a folder called “sprite” (see our directory structure above).

$sprite-sprite-base-class: '.sprite';
$sprite-layout: smart;
$sprite-sprite-dimensions: true;

@import "compass/utilities/sprites/base";

@import "../images/sprite/*.png";
@include all-sprite-sprites;



A quick breakdown of the few options we set:

  • $sprite-sprite-base-class: Tells Compass to define one additional class with the sprite as its background-image. Use as $<folder name>-sprite-base-class.
  • $sprite-layout: This tells Compass how we want our images laid out within the sprite. The options are vertical, horizontal, diagonal and smart. Smart means that it packs all the images in together as tight as possible so that the footprint of the final sprite is as small as possible. Use as $<folder name>-layout.
  • $sprite-image-dimensions: Tells Compass to include the dimensions of each individual image in the CSS along with its coordinates. Use as $<folder name>-image-dimensions.



Note that there are many other customizations you can set for your sprite, but these 3 did the job for us. For the full list of options, check out the documentation at http://compass-style.org/help/tutorials/spriting/customization-options/.

The final step is to @import the Compass sprite module and all of the images we want compiled into a sprite. Then, by calling the magic function all-sprite-sprites (all-<folder name>-sprites), Compass will dig into our sprite folder, stitch everything together, drop a CSS file into our css folder and a complete sprite into our images folder. The result is:

  1. A complete sprite.

  2. A complete CSS file. Ours is big (look at all those icons!), so here’s a sample:
    .sprite, .sprite-dashed-border-add-file, .sprite-icon-actionstep-focus, .sprite-icon-actionstep-overdue, .sprite-icon-actionstep-today {
      background: url('/images/../images/sprite-s134b848ff6.png') no-repeat;
    }
    
    .sprite-dashed-border-add-file {
      background-position: 0 -177px;
      height: 145px;
      width: 342px;
    }
    
    .sprite-icon-actionstep-focus {
      background-position: -293px -64px;
      height: 27px;
      width: 24px;
    }
    
    .sprite-icon-actionstep-overdue {
      background-position: -269px -64px;
      height: 27px;
      width: 24px;
    }
    
    .sprite-icon-actionstep-today {
      background-position: -245px -64px;
      height: 27px;
      width: 24px;
    }
    



At this point, it’s important to note that obviously the path to your image is wrong if you’ve kept our config.rb function to rename and move the file. However, I’m totally okay with this, because I don’t love that first rule anyhow (too many selectors for my taste), so the first thing I do after compiling a sprite is change it to be simpler and more useful:

.sprite {
  display: inline-block;
  background: url('../sprite.png');
}

Now, for any element that should be an icon, I just apply two classes: sprite and whichever class references the icon I’m looking for. If you ever need to add any more icons to your sprite, just drop the images into your folder and let the sprite re-compile. All the existing class names stay the same, so any new background positions are automatically reflected. You don’t have to change any of your markup.

Spriting has never been more blissful.

If you have any questions about anything in this blog post, or you just want to talk about Sass and Compass, leave a comment below or follow me on Twitter at @jackiebackwards.

21 comments

  1. Alexander Albrecht
    — August 2, 2012 6:11 pm

    You should look into inline-image with SASS. It encodes your sprites to base64. With gzip compression you can get an even smaller footprint.

  2. catalinx
    — October 28, 2012 9:38 pm

    Is there any way to put images from two folders in the same sprite image?

  3. — December 1, 2012 4:09 am

    I’ve been absent for a while, but now I remember why I used to love this website. Thanks , I

  4. — December 3, 2012 12:25 am

    Hi would you mind stating which blog platform you

  5. — December 7, 2012 3:23 pm

    Hey there would you mind letting me know which web host you’re working with? I’ve loaded your blog in 3 completely different internet browsers and I must say this blog loads a lot faster then most. Can you suggest a good web hosting provider at a reasonable price? Kudos, I appreciate it!

  6. This has to be one of my favorite posts! And on top of thats its also very useful topic for newbies. thank a lot for the info!

  7. Nate
    — December 11, 2012 10:08 pm

    Hi I just wanted to say that this blog was a great resource for me in improving my experience with using compass to create sprites!

    One thing I wanted to add is that while I agree with not liking the huge string of selectors it attaches to the background image, I also do not like having to add the extra “sprite” class to every element. So I went with [class*="sprite-"] and get the same result with no extra markup. I realize the potential downside to this if that ever matched an unintended element, but there is currently only myself and one other developer and proper comments are in place.

    I would be interested in hearing everyone’s opinion.

  8. — February 15, 2013 12:10 am

    i really liked your post, i couldnt seem to find much on the internet

  9. — June 7, 2013 3:46 pm

    What’s up, just wanted to say, I enjoyed this post. It was inspiring. Keep on posting!

  10. — September 13, 2013 4:21 am

    Thanks for finally talking about >Compass and Slicy Wiill Make Your Sprites and Write Your CSS onn the Behance Dev Blog <Loved it!

  11. — September 28, 2013 4:05 am

    I like the valuable info you provide in your articles. I will bookmark your blog and check again here frequently.
    I am quite certain I will learn many new stuff right
    here! Good luck for the next!

  12. — October 4, 2013 4:23 am

    No matter if some one searches for his required thing, thus he/she desires to be available that in detail, therefore
    that thing is maintained over here.

  13. — October 11, 2013 5:05 am

    Hi, I think your blog might be having web browseer compatibility problems.
    Whenever I take a look at your site inn Safari, it looks fine however when opening in Internet Explorer, it hhas some overlapping issues.
    I merely wanted to give you a quick heads up! Apart from that, excellent blog!

  14. — October 13, 2013 4:45 pm

    Her response was that I had too forgiving a nature; that I was too open and trusting.
    At the time I must admit that I thought her reaction
    was a bit over the top. Crops which require up to 24 hrs to mature help you bring in two knowledge factors on just
    about every plot of land.

  15. Ray
    — October 16, 2013 4:06 am

    Change was needed in the industry and Rockstar Games stepped up.

  16. — October 17, 2013 1:22 pm

    Fabulous, what a website it is! This blog provides useful information tto us, keep iit up.

  17. — October 31, 2013 5:09 am

    I am sure this post has touched all the internet viewers, its really really pleasant paragraph
    on building up new website.

  18. — December 8, 2013 8:04 am

    I leave a response when I especially enjoy a post on a website or if I have something
    to contribute to the discussion. It’s a result of
    the passion displayed in the post I read. And after
    this article Compass and Slicy Will Make Your Sprites and Write Your CSS on the Behance Dev Blog.
    I was moved enough to drop a leave a responsea response ;-) I actually do have a couple of questions
    for you if you usually do not mind. Could it be only me or does it give the impression like a
    few of the remarks come across like written by brain dead folks?

    :-P And, if you are posting on other social sites, I would
    like to keep up with you. Could you make a list the complete urls of your shared sites like your
    linkedin profile, Facebook page or twitter feed?

  19. — January 21, 2014 11:56 am

    Wonderful, what a blog it is! This web site gives helpful
    information to us, keep it up.

  20. — January 25, 2014 7:57 am

    At this time it appears like Expression Engine is the top blogging platform out
    there right now. (from what I’ve read) Is that what you’re using on your blog?

  21. — March 22, 2014 7:04 am

    Heya! I’m at work browsing your blog from my new iphuone 3gs!
    Just wanted to say I love reading your blog and look forward to all your posts!

    Keep uup the great work!

Submit