Skip to content

Instantly share code, notes, and snippets.

Last active January 7, 2016 19:24
What would you like to do?
Using Yeoman with Compass Sprites

Yeoman + Compass Sprites


generator-webapp has support for compass out of the box. However, in order to use one of my favorite features of it — sprites and the image_url helper — you have to make some adjustments to the Gruntfile.

Let's assume you use a SASS stylesheet like this one:

@import "design/*.png"

    display: block
    width: design-sprite-width('icon')
    height: design-sprite-height('icon')
    background: transparent image_url('logo.png') no-repeat
    width: 64px
    height: 64px

This assumes that you have an icon.png file in your app/images/design/ folder and a logo.png in app/images/. In the default configuration, compass will generate incorrect paths to the file.


To fix that, you have to make some adjustments to the Gruntfile.js:

compass: {
    options: {
        sassDir: '<%= %>/styles',
        cssDir: '.tmp/styles',
        imagesDir: '<%= %>/images',
        javascriptsDir: '<%= %>/scripts',
        fontsDir: '<%= %>/styles/fonts',
        importPath: 'app/components',
        // The next line tells compass where to put the sprites
        // and the HTTP path to them.
        raw: 'http_images_path = "/images/"\ngenerated_images_dir = ".tmp/images"\nhttp_generated_images_path = "/images/"',
        // This doesn't work with relative paths.
        relativeAssets: false
imagemin: {
    dist: {
        files: [{
            expand: true,
            cwd: '<%= %>/images',
            src: '{,*/}*.{png,jpg,jpeg}',
            dest: '<%= yeoman.dist %>/images'
        }, {
            // Copy generated sprites over to the dist/
            // folder during the build step.
            expand: true,
            cwd: '.tmp/images',
            src: '{,*/}*.png',
            dest: '<%= yeoman.dist %>/images'

Now you're done and should be able to use sprites both in server and production mode.


The usemin has troubles detecting images referenced by the image_url helper and replacing them with the revved version, because compass appends a timestamp on them. You can either disable the cache buster feature of compass, or disable the rev task to work around this.

Copy link

Good tip on usemin and asset_cache_buster :none.

Copy link

anacronw commented May 1, 2013

unfortunately, it seems like asset_cache_buster still doesn't remove the hash? This is according to the SO:

Is it advisable to have the Gruntfile config point to the actual config.rb file in order to implement the function recommended by the SO answer?

Copy link

anacronw commented May 1, 2013

Things I want to add in light of trying the SO answer above:

My compass config looks like this:

            options: {
                sassDir: '<%= %>/styles',
                cssDir: '.tmp/styles',
                imagesDir: '<%= %>/images',
                javascriptsDir: '<%= %>/scripts',
                fontsDir: '<%= %>/styles/fonts',
                importPath: 'app/components',
                relativeAssets: false,
                config: '.compass.rb'

My .compass.rb config file:

http_images_path= '../images'
generated_images_dir = ".tmp/images"
http_generated_images_path = "../images/"
asset_cache_buster :none

on_sprite_saved do |filename|
  if File.exists?(filename) filename, filename.gsub(%r{-s[a-z0-9]{10}\.png$}, '.png')

# Replace in stylesheets generated references to sprites
# by their counterparts without the hash uniqueness.
on_stylesheet_saved do |filename|
  if File.exists?(filename)
    css = filename, 'w+') do |f|
      f << css.gsub(%r{-s[a-z0-9]{10}\.png}, '.png')

Finally, make sure you modify the default Yeoman Gruntfile's concurrency task. You want to move compass:dist out of concurrent so that compass sprites can be generated into app/images before executing imagemin:

        concurrent: {
            server: [
            test: [
            dist: [
                //'compass:dist', // moved this out
 grunt.registerTask('build', [
        'concurrent:dist', // added this here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment