Automating spritesheet creation with GruntJS

In my previous post, i was talking about how GruntJS can optimize your workflow by automating a lot of repetitive tasks. If you don’t have any experience with GruntJS, i suggest you to read my initial blog post about How to improve your workflow with GruntJS to get familiar with the program.

As a web developer, i always care about webpage performance and optimization. I always want to give a fast and efficient website to my client. That’s why part of my job is to create image spritesheet to speed up loading time by minimizing the number of server requests.

Initially, i was creating my spritesheet in Photoshop. It was painfull, was taking a lot of time and was pretty hard to manage over time. Definitively not the best approach but it was the only tool i know that would do the job. At least, the speed improvement were justifying the effort.

When i discovered GruntJS, i knew that there was a better way to automate image spritesheet creation using this tool. A quick Google search take me to this NodeJS module, which support GruntJS tasks, by Richard Butler. This library does all the hard job and even more. It’s simply amazing! It even support pixel ratios for creating high resolution spritesheet for high density screen and normal resolution for regular screen!

Installation

First, open Terminal and navigate to your project grunt.js folder. Then type npm install node-spritesheet — save-dev to install the module into your project.
After installation completed, load the module into your grunt.js file by adding grunt.loadNpmTasks(‘node-spritesheet’); before your tasks registrations.
Once installed and loaded, node-spritesheet is ready to use.

Folder structure

I create the following folder structure.

my-project/ 
img/
styles/
src/
img/
legacy/
spritesheet/

I keep all my sprite images in src/img/normal and output the resulting spritesheet in img/.
As i still support IE7 and IE8, i often need to create images to emulate CSS3 features like gradient, border radius or drop-shadow. I put these images in src/img/legacy/.
Then, i’m using Photoshop to save PNGs of all these sprites to these two directories, depending of the case.

Configuration

This is where all the magic happen. I’m creating two spritesheets. One for legacy browsers that include only the images to emulate CSSS3 features and another for the rest.
Open your grunt.js file and write this snippet down:

The task look at all images located in /src/img/ and filter files based on her parent folder name. If image is in /src/img/legacy/, it will be used in the legacy spritesheet. Otherwise, it will be part of the default spritesheet. It create two resulting PNG spritesheets and a resulting CSS file. The CSS file contains all sprites classname and x,y position in the spritesheet.

I’ve also setup a watch tasks that look at /src/img/ folder and launch the spritesheet task when a change occur to any file. Needless to say that it’s a huge timesaver.

Using the resulting spritesheets and stylesheet in your html

First, you need to include the stylesheet into your HTML document. Create index.html at your project root folder and use the following code:

Note: node-spritesheet may have incorrectly setup spritesheet path in the stylesheet. If it’s the case, i suggest you to override the .sprite and .sprite-legacy classes like this:

<style>
.sprite { background-image: url(img/spritesheet.png); }
.sprite-legacy { background-image: url(img/spritesheet-legacy.png); }
</style>

To use a sprite from spritesheet, simply add sprite class to the HTML element and the corresponding sprite.filename class like in the example above.
Use the same method to use legacy spritesheet by replacing the sprite class to sprite-legacy and by using the corresponding sprite position. (ex: sprite-legacy.filename)

Conclusion

It’s very easy to automate spritesheet generation with GruntJS. It will save time and effort and will help you maintaining your spritesheet in the future. I will never look back at Photoshop for creating and managing my spritesheet.