Alternatives to Compass in a Rails project

For years we were using Compass with Sass with our product, Krrb, to make our lives (mine at least) a bit easier:

  • no browser prefixes to take care off
  • cool shortcuts
  • easy image sprites generation

However, there were still performance issues.

Compass is huge and take lots of time to compile—from five to eight seconds for each deploy. So I decided to get rid of it completely.

Also I didn’t want to have another framework to maintain like Bourbon. Bourbon is light and a good choice if you want to do complex css animations but this is not an issue with an application like Krrb. I prefer adding my own tools rather than including a whole new framework.

Mixins

I started to add some precious mixins that mimic some features I was using on Compass:

Headings:

Compass is using headings($from, $to)
compass-style.org/reference/compass/helpers/selectors/#headings

Which has been translated to this mixin :

@mixin headings($from: 1, $to: 6) {
    @for $i from $from through $to {
      h#{$i}{ @content }
    }
}

Image-width and Image-height

Compass is great for image dimensions :
compass-style.org/reference/compass/helpers/image-dimensions/

Luckily, I found a gem that brings the exact same functionalities with cleaner code:
github.com/ai/rails-sass-images

It also handles inline for fonts or SVGs which is great.
I also created other mixins for border-radius, opacity, box-shadows, box-sizing etc.

Here are a few of them:

@mixin font-smoothing($value: on) {
 @if $value == on {
 -webkit-font-smoothing: antialiased;
 -moz-osx-font-smoothing: grayscale;
 } @else {
 -webkit-font-smoothing: subpixel-antialiased;
 -moz-osx-font-smoothing: auto;
 }
}

@mixin box-shadow($shadows...) {
 -webkit-box-shadow:$shadows;
 -moz-box-shadow:$shadows;
 box-shadow:$shadows;
}

@mixin box-sizing($box-model) {
 -webkit-box-sizing: $box-model;
 -moz-box-sizing: $box-model;
 box-sizing: $box-model;
}

@mixin border-radius($radius: 2px) {
 border-radius: $radius;
 -moz-border-radius: $radius;
 -webkit-border-radius: $radius;
 background-clip: padding-box;
}

Sprites

Now that the mixins issue was solved, I needed a way to re-generate the image sprites. Even if I tried to avoid image sprites and wanted to turn all our assets to svgs, I can’t get rid of them right now. This would mean vectorizing thousands of pngs.

Then I found this gem called Spriteful.
github.com/lucasmazza/spriteful

The command is:

bundle exec spriteful -f scss --rails --mixin --template app/assets/stylesheets/templates/template.scss.erb -destination app/assets/images -stylesheets app/assets/stylesheets/mixins/ --spacing 10

It creates multiple sprites with lots of freedom in the output and is fast. The result is a set of mixing that you can use to define icons so you have freedom in the class name definitions.

I don’t like the idea of using a script that will tell you how to write HTML. HTML should guide the CSS, not the opposite.

Plus, I wanted the output to cover retina support and add dimensions so I ended up using a custom template to generate the mixins:
gist.github.com/mrdoinel/be81f4ee183d8408fca5

The result generated this scss logic :

.warning {
  @include i-sprite-warning;
}
/* Or if you want to have the dimensions of the image added to the css rule : */
.warning {
  @include i-sprite-warning-dim;
}

An icon called “warning.png” needs to live in the folder called sprites/i and another one called sprites/i2x (for retina).

And voila!

Just curious, do you guys know any other ruby gems that enhance Sass?