CSS Sprites with Sass and Compass
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:
- Import the required Sass assets (variables, mixins, functions) from the corresponding module (Utilities).
- Import all the images (sprites) that are in the
icons
folder. - Include the Sass mixin that will generate the CSS classes for the sprites.
- 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:
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
orfalse
. 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:
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 thebackground-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.