HTML & CSS
Article

CSS Sprites with Sass and Compass

By George Martsoukos

Building robust websites and applications isn’t just writing semantic HTML and fancy CSS. It’s also important to keep an eye on web performance from the beginning of your projects. There are many techniques that can help with this, and thus create a better user experience. Creating CSS sprites is one of them. Using this technique you combine all of your small images (sprites) into a larger image (sprite sheet) along with CSS to position it.

You can generate your sprites using different tools, yet in this article I’ll show you how to achieve it using Compass. Before that, let me introduce you to the project that will be used for this article.

Setting up a project

To better demonstrate how Compass’s sprite builder works, I set up a new project. Here’s the structure of it:

Compass-Sprites/
├── config.rb
├── index.html
├── stylesheets/
│     ├── ie.css
│     ├── print.css
│     └── screen.css
├── sass/
│     ├── ie.scss
│     ├── print.scss
│     └── screen.scss
└── images/
    └── icons/
        ├── arrow-down.png
        ├── facebook-active.png
        ├── facebook-hover.png
        ├── facebook.png
        ├── twitter-active.png
        ├── twitter-hover.png
        ├── twitter.png
        └── zuckerberg.png

Notice, there’s an icons folder within the images folder, which contains all the images that will be used for this project.

You can grab all the files for this project by downloading this zip file.

Basic Spriting

Creating a sprite sheet is a 4-step process:

  1. Import the required Sass assets (variables, mixins, functions) from the corresponding module (Utilities).
  2. Import all the images (sprites) that are in the icons folder.
  3. Include the Sass mixin that will generate the CSS classes for the sprites.
  4. Add the generated classes to the related HTML elements.

To be more specific, in the screen.scss file we add the following directives:

@import "compass/utilities/sprites";
@import "icons/*.png";
@include all-icons-sprites;

Again, notice that icons is the name of the folder containing the images.

As long as we save and compile the screen.scss file the sprite sheet will be created in the images folder. The name of the sprite sheet would look like this:

icons-s82ea51d311.png

The name of it retains the following convention: <Images_Folder_Name>-<Cache_Buster>. The cache buster changes every time we update the sprite sheet. In this way, the browser will always have and use the latest version of it.

The initial sprite sheet of our project will look something like this:

default compass sprite compilation

And here are the CSS classes that Compass generates for us:

.icons-sprite,
.icons-arrow-down,
.icons-facebook,
.icons-twitter,
.icons-zuckerberg {
  background-image: url('../images/icons-s82ea51d311.png');
  background-repeat: no-repeat;
}

The names of the classes above have the following convention: <Images_Folder_Name>-<Image_Name>.

For each image, Compass applies a different background position. For example, here’s the background-position for the zuckerberg.png image:

.icons-zuckerberg {
  background-position: 0 -232px;
}

At this point we add the generated classes to the corresponding HTML elements.

Here’s the element that is related to the zuckerberg.png image:

<h1 class="icons-zuckerberg">Mark Zuckerberg</h1>

Keep in mind that Compass API can generate a sprite sheet only for PNG images.

Magic Selectors

Compass has the ability to create classes for different states using the sprite magic selectors.

For instance, in our project there’s the facebook.png image. Let’s say that we want to have different background colors for the images for the hover and active states. In this case, we add the facebook-hover.png and facebook-active.png images. The names of these images should follow the convention: <Image_Name>-<State>.

After that, Compass generates the following CSS classes:

.icons-facebook:hover, .icons-facebook.facebook-hover {
    background-position: 0 -72px;
}
.icons-facebook:active, .icons-facebook.facebook-active {
    background-position: 0 -40px;
}

Customizing the Generated Classes

In the previous sections, we saw how Compass can generate the CSS classes. But, what if we want to customize the names of these classes? Hopefully, we can do it using the <Images_Folder_Name>-sprite(Image_Name) mixin, instead of the all-<Images_Folder_Name>-sprites mixin.

To illustrate this, let’s assume that we want to change the name of the icons-zurckerberg class. In the screen.scss file we add the following class:

.creator {
    @include icons-sprite(zuckerberg);
}

This class is derived as follows:

<Desired_Class_Name> {
    @include <Images_Folder_Name>-sprite(Image_Name);
}

And here’s the CSS that is created and can be applied to the element we want:

.creator {
    background-position: 0 -232px;
}

Notice that the only thing that changes is the name of the class attribute. The CSS properties have the same values as the first mixin.

The advantage of the second mixin is that it offers you the option to create your custom classes. However, this might not be a good solution if your project has a lot of images.

Configuration Options

Compass allows us to customize the sprite sheet using additional configuration variables. Here are some of them:

  • $sprite-selectors: Determines the states for which the magic sprite selectors are enabled. Possible values: hover, target, active, focus. Default values: hover, target, active, focus.
  • $disable-magic-sprite-selectors: Determines if the sprites will contain magic selectors. Possible values: true or false. Default value: false.
  • $icon-layout: Determines the layout of sprites in the sprite sheet. Possible values: horizontal, vertical, diagonal, smart. Default value: horizontal.
  • $icon-spacing: Determines, in pixels, the amount of spacing between each sprite. Default value: 0.
  • $sprite-dimensions: Determines if the generated CSS classes will contain the dimensions of each sprite. Default value: false.
  • $default-sprite-separator: Determines the default separator for the sprites. Possible values: - or _ . Default value: -.

The variables above should be defined before creating our sprite sheet. That means, before adding the following directive:

@import "icons/*.png";

Let’s now experiment with two of them in our project.

As a first attempt, we change the sprite sheet layout to smart adding the following variable:

$icons-layout:smart;

This results in the following sprite sheet:

compass sprites smart compilation

It’s worth mentioning that we can’t use the smart method and the $icon-spacing variable at the same time. This happens because the method arranges the sprites in an optimal way removing as much white space between them as possible.

Now let’s see what happens when we add the variable below:

$icons-sprite-dimensions:true;

When compiled we get something like this CSS output for one of the generated classes:

.icons-facebook {
    height: 32px;
    width: 32px;
}

So what’s happened? Compass has the ability to measure the dimensions of each image and output them in the compiled CSS. This is a great feature, which could be useful when the sprite sheet contains images that have different dimensions. However, if we have images with same dimensions this could result in bloated CSS.

Beyond the Basics

As we have previously seen, creating a sprite sheet requires the following magic directives:

@import "<Images_Folder_Name>/*.png";
@include all-<Images_Folder_Name>-sprites;
@include <Images_Folder_Name>-sprite(Image_Name);

Beyond them, there are also some extra functions and mixins we can use to create our sprite sheet. Here are some of them:

  • sprite-map: A function that creates a CSS sprite map containing the images.
  • sprite: A mixin that returns the image and the background-position of it.
  • sprite-dimensions: A mixin that returns the dimensions of the sprite.

To better understand how these work, let’s again assume that we want to create a custom class with name creator. We define the sprite map (requesting a smart layout) and get the background-position of the icons-zurckerberg.png image. Then, we retrieve the dimensions of this image. After, we’re ready to assign this class to the desired HTML element.

Here’s the code that invokes what is described above:

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

.creator {
    background: sprite($icons, zuckerberg);
    @include sprite-dimensions($icons, zuckerberg);
}

And here’s the CSS:

.creator {
    background: url('../images/icons-s855a77086a.png') 0 -232px;
    height: 190px;
    width: 190px;
}

Conclusion

In this article, I briefly introduced you to the concept behind the CSS sprites technique. Then, I showed you the basics of Compass’s sprites generator. There are more options than we have covered here, but I hope you got the idea of generating sprites with Compass.

Comments
mikestreety1

I did do a write up on SVG sprites, with Gulp and Sass if anyone is interested.

https://www.liquidlight.co.uk/blog/article/creating-svg-sprites-using-gulp-and-sass/

Great article though!

georgemarts

Interesting! Thanks for sharing it!

Recommended
Sponsors
Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in Front-end, once a week, for free.