Create a gist now

Instantly share code, notes, and snippets.

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.

Good tip on usemin and asset_cache_buster :none.

badunk 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?

badunk 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