Jamie Sutherland
Jamie Sutherland

Reputation: 2790

Compass creating multiple sprite files for different coloured themes under the same icon name

I'm looking to do the following and I just can't seem to work out how without a fair amount of fiddling.

I want to have two icon sets for my theme. One black. One white. My theme has two different colour schemes you can pick from. Grey and blue. On the grey theme, I want black icons, on the blue theme I want white.

I have created my original black icon set fine and have included them in a folder icon/*.png

Now what I'd like to use is the Nested Folder setup where my icons are in the following folders icon/black/*.png and icon/white/*.png

The problem with this is my icons will be named like so black-add and white-add where what I really want is icon-add so that I don't have to change my themes @import icon-sprite(add) lines and I just include the correct sprites/_black or sprites/_white in the top level theme sass file.

Is there some configuration I'm missing that allows me to do this? or am I going about this in the wrong way?

I've worked around the issue by creating a generic icon/*.png folder with all the icons, then copying the generated _icon.sass file and editing it for the black and white icons. then includeing 'sprites/black' in my grey theme and 'sprites/white' in my blue one. This works, but it's a bit of a PITA when you want to add new icons.

Any help here would be greatly appreciated!

UPDATE for clarification

Current folder structure.

themes/
    images/
        default/
            icon/
                black/
                white/
        blue/

config.rb

# $ext_path: This should be the path of the Ext JS SDK relative to this file
$ext_path = "../"

# sass_path: the directory your Sass files are in. THIS file should also be in the Sass folder
# Generally this will be in a resources/sass folder
# <root>/resources/sass
sass_path = File.dirname(__FILE__)

# css_path: the directory you want your CSS files to be.
# Generally this is a folder in the parent directory of your Sass files
# <root>/resources/css
css_path = File.join(sass_path, "..", "css")

images_path = File.join(sass_path, "..", "themes", "images", "default")
generated_images_dir = File.join(sass_path, "..", "themes", "images", "default")
generated_images_path = File.join(sass_path, "..", "themes", "images", "default")
http_generated_images_path = File.join("..", "themes", "images", "default")
sprite_load_path = File.join(sass_path, "..", "themes", "images", "default")

# output_style: The output style for your compiled CSS
# nested, expanded, compact, compressed
# More information can be found here http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#output_style
output_style = :compressed

# We need to load in the Ext4 themes folder, which includes all it's default styling, images, variables and mixins
load File.join(File.dirname(__FILE__), $ext_path, 'themes')

Re-reading my config file, it's like I want to have multiple entries for sprite_load_path or take away the "default" join.

Upvotes: 2

Views: 1974

Answers (2)

David Pelaez
David Pelaez

Reputation: 1384

The solution that I encountered mixes @maxbeatty solution with magic generation of the selectors to keep compass' sexyness. Basically you have one sass template for each style where the sprite has the very same name and nest the selectors under different classes for each color. Assume the previously mentioned file structure:

/images
|
--/themes
  |
  --/grey
    |
    --/icon
      |
      -- add.png
  --/blue
    |
    --/icon
      |
      -- add.png

With that file structure in mind you can have a folder called sprites in your stylesheets and then inside that, one sass template for each style. Eg. you will have:

--/stylesheets/sprites
          |
          -- grey.sass
          -- blue.sass
          -- all.css (explained below)

The files are the same except for the corresponding changeable part marked as [color]:

@import themes/[color]/icon/*.png

.[color]
    @include all-icon-sprites

Then you will want to have both files compiled and then imported. You must be careful, because merging them before compilation might cause sass to join some selectors and eliminating the separation. What I did in rails was to have a .css manifest importing the compiled versions rather than merging them using sass import directive:

/stylesheets/sprites/all.css:

/*
*= require_tree .
* Import the compiled versions of the sprites. 
* Prevents SASS from mixing them and applying the same sprite to all selectors
*/

This in the ends gives you something like:

.blue .icon-home
.gray .icon-home

This of course has the downside of having to nest your icons under a parent where you set the color. It's annoying, but not terrible considering that you will have magic sprite generation.

NOTE: Stack Overflow has been very helpful for me and now I'm trying to contribute back. If this was helpful please consider voting up.

Upvotes: 1

maxbeatty
maxbeatty

Reputation: 9325

You can change the sprite base class but that won't help you with your individual @include.

It's not completely clear how your entire project is currently organized, but I would suggest tying your image folder hierarchy closer to your themes than the color of the icons.

/images
|
--/themes
  |
  --/grey
    |
    --/icon
      |
      -- add.png
  --/blue
    |
    --/icon
      |
      -- add.png

Since Compass uses the last directory in the path for the map name, you can @import "themes/grey/icon/*.png" which will allow you to use @include icon-sprite(add)

You can also "read" your file structure as "the add icon for the blue theme"

Upvotes: 1

Related Questions