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?
Interesting. I just switched from Compass-oriented workflow to a Gulp-oriented one (see , the logic being that it’s nice to keep the front-end processes somewhat independent of back-end tech. Did you consider going that route? I like the potential future-proofness of stitching together small utilities (autoprefixer, image optimization, js concatenation), each of which does its job well.
Funny! Using a Grunt/Gulp/Broccoli workflow on Ruby project is a discussion we are having right now. Thank you for your comment!
There are still a few blockers for me but having the front-end processes independent of back-end tech is where we want to go.
For example :
— Are the minified CSS/JS files in version control ? This could create massive git conflicts. If not, this mean that your servers need to be up-to-date with your gulpfile when deploying the app, so the tasks are generating properly the assets.
— How do you deal with caching and image-path() helpers ? No asset pipeline at all ? I like how this deal the cache busting for example!
Antoine
You can add your generated files in the .gitignore, with your gulpfile versionned. And when you push your modifications, you can have a git hook which will run the gulpfile server side.
I don’t work with Rails pipelines and I run the tasks locally and only deploy the build files, so I don’t have any great answers to your questions. But to me the Gulpfile is equivalent to Compass’s config.rb and a Gulp workflow doesn’t really introduce any additional problems, does it?
If you miss Compass’s inline-image function for encoding SVGs as data-URIs, check out https://www.npmjs.org/package/gulp-base64.
Interesting, running the gulpfile server side using git hooks mean that you generate assets only when merging a branch to the production one for example. In theory the production/staging servers don’t need have the proper npm packages installed right ?
But this idea seems a bit weird for me : having your front-end relying on the version control system.
You could have a look at Susy for grid management. The version 2 no longer requires Compass. http://susy.oddbird.net
Hello Hans, I never used it but this looks nice, especially the gutter(s) mixins.