HTML & CSS
Article
By Hugo Giraudel

Why I Don’t Use Compass Anymore

By Hugo Giraudel

Compass is one hell of a project. It is by far the biggest Sass framework out there and since it is maintained by Chris Eppstein himself, one of the two Sass core designers, I don’t see it losing in popularity anytime soon.

Yet, about a year ago or so, I stopped using Compass altogether. I removed it from our project at work. I removed it from my own site. I removed it from most of my side projects. So what happened? How could I move from “Compass is the best” to “I don’t need it anymore”?

I think I just got better and more confident with Sass, to a point where Compass did not bring much to the table anymore. At least, it was not enough to be worth including it in a project, especially given that it slows Ruby Sass, already quite slow in itself…

Let me put something straight before going any further: in no way am I saying that Compass is useless. Neither am I saying that you should get rid of Compass. I only want to show you other options and other ways of doing things, that do not require Compass to be part of the project.

Now, to fully get why we can or cannot remove the Compass dependency, we need to understand what does Compass do at the end of the day. According to the docs, Compass provides:

Everything else is pretty much accessory.

--ADVERTISEMENT--

Autoprefixer does the same

Before Compass 1.0.0, prefixes were managed manually in Compass. It means whenever a new prefix was born or passed away, a pull request had to be submitted to Compass to remove the prefix from the relevant mixin. Not ideal… That’s why Chris moved to something smarter in v1.0.0, pulling data directly from CanIUse.

Meanwhile, the very popular Autoprefixer library does the same. So at this point, both Compass and Autoprefixer are 100% up-to-date with vendor prefixes, yet there is still a major difference: you still have to use Compass mixins to prefix your properties and values, while Autoprefixer does it as part of your deployment process, post-processing your stylesheets.

In order to have the following CSS output:

.unicorn {
  -webkit-transform: translateX(42em);
  -ms-transform: translateX(42em);
  transform: translateX(42em);
}

You need to write this in Compass:

.unicorn {
  @include transform(translateX(42em));
}

And this with Autoprefixer plugged in:

.unicorn {
  transform: translateX(42em);
}

Not only is the latter easier and shorter, also in the hypothetical and marvelous future where we no longer need prefixes for the transform property, we don’t have to come back to the code to get rid of the mixin call. It’s all good.

You don’t need math everyday

I like how Sass provides us with the ability to perform math operations within our stylesheets. When we think about CSS preprocessors, we often mention variables and mixins, yet omit math support. This is a huge deal for a number-based language such as CSS.

On top of that, Compass provides a few advanced math helpers, such as cos, sin, tan, sqrt, pow, pi and, perhaps, less usefully acos, asin, atan, logarithm and e. In some cases, I have to admit having access to those functions might be useful. For instance,
in a previous article I used cos and sin to build the perfect long-shadow mixin. A while back, I remember needing sqrt to properly align rotated pseudo-elements as part of a step-wizard. So there are use cases.

Yet, they are so uncommon that I cannot consider Compass’ math helpers a valid reason to keep it in a project. It, for me, is just too anecdotal at this point. Especially since most of those functions can be polyfilled with nothing but Sass (thanks to basic math operations). For instance, here is a pure Sass version of the pow function:

/// Power function
/// @param {Number} $x
/// @param {Number} $n
/// @return {Number}
/// @source https://github.com/adambom/Sass-Math/blob/master/math.scss Sass-Math
@function pow($x, $n) {
  $result: 1;

  @if $n >= 0 {
    @for $i from 1 through $n {
        $result: $result * $x;
    }
  } @else {
      @for $i from $n to 0 {
        $result: $result / $x;
      }
    }
  @return $result;
}

If you extensively need advanced math functions in Sass, may I recommend having a look at Sassy-Math, a lightweight Ruby Sass library providing everything math. If you want to polyfill a math function yourself, have a look at this article. Also, Ana Tudor has written about inverse trigonometric functions in Sass at The Sass Way.

You can polyfill color functions

I must say I am not an expert with Compass color functions since I never used any of them. The thing is Sass already provides so many native functions to deal with colors that I never felt like some more were needed.

Although, that’s not entirely true. In Sass Guidelines I explain how I think using the mix function is often more appropriate than darken and lighten. To make using mix slightly easier, I wrote two very short functions that happen to exist in Compass:

/// Slightly lighten a color
/// @access public
/// @param {Color} $color - color to tint
/// @param {Number} $percentage - percentage of `$color` in returned color
/// @return {Color}
@function tint($color, $percentage) {
  @return mix($color, white, $percentage);
}

/// Slightly darken a color
/// @access public
/// @param {Color} $color - color to shade
/// @param {Number} $percentage - percentage of `$color` in returned color
/// @return {Color}
@function shade($color, $percentage) {
  @return mix($color, black, $percentage);
}

Anyway, there again I don’t think this is enough to keep Compass exclusively for this.

Watch AtoZ: Sass

Learn Sass letter by letter

You can do without image helpers

Let’s get to the real thing. Compass, being that it is written in Ruby, provides image helpers such as image-width and image-height that return an image’s dimensions based on a given path. How great is this, especially for image replacement techniques? This way you can size an element to fit an image, without worrying about the dimensions changing.

.logo {
  $logo-path: '/assets/images/logo.png';
  width: image-width($logo-path);
  height: image-height($logo-path);
  // ...
}

Unfortunately, there is no way for us to polyfill such a thing. Sass does not have access to the file system so it is not possible to figure out an image dimensions whatsoever.

That being said, I personally tend to use less and less images in my work when using SVG or any equivalent is an option. Because SVG stands for scalable vector graphics, I think the need to know exact dimensions is getting lower everyday. As far as I am concerned, I have not missed this feature for a while now.

SVG Sprite Builders are legions

Okay, now we’re talking. The sprite builder has always been Compass’s main feature if you ask me. And for that reason, it is extremely well thought and convenient. Building a spritesheet from an image folder only takes a couple of minutes with Compass, if not less.

@import "compass/utilities/sprites";
@import "my-icons/*.png";
@include all-my-icons-sprites;

Fine. While there were no strict equivalent for image helpers, we all know that there are countless sprite builders out there. Take Grunticon for instance, a SVG sprite builder running on Grunt. It even comes with a browser-based app entitled Grumpicon. This is probably one of the best since it has been released by Filament Group but there are plenty of other choices, running on whatever tool floats your boat.

So while it is nice having Compass doing that directly from our stylesheets, there are other options and it is indeed possible to handle sprites without having to use Compass. Along the same lines, I would find it very odd to use Compass only for the sprite builder, no matter how good it is. A sprite builder is a tool that can be completely dissociated from the stylesheet itself. There is no need for both to be intimately tied, even if it might present some benefits.

A word about LibSass

Compass is not LibSass compliant. Because it still is heavily tied to Ruby, it is not possible to use Compass in a “LibSass environment”. In a world where LibSass is getting more and more present every day, I think being engine-agnostic is a major goal. Obviously, Chris thinks the same and will work on porting it to LibSass.

Final thoughts

Moving away from Compass, if that’s what you want, should be relatively simple. First, make sure you do not use any helpers from Compass such as tint or sqrt. If you do, polyfill them in your function files (just Google them, you’ll find a pure Sass version soon enough). Then, get rid of all your CSS prefixing mixins and set up Autoprefixer in your project (if that’s possible, obviously). Last, move to a custom sprite builder if you need it.

Again, it is not that Compass is a bad tool or anything. Au contraire, Compass is a terrific framework! If you are happy with Compass, please keep using it. There is no point in dropping a tool you are happy with just because you read it from some article, so stick to Compass if you are fine with it.

On the other hand, if you wonder whether it’s worth moving away from Compass because you don’t use much of it, then you might consider getting rid of it, as I did.

The most important and interesting stories in tech. Straight to your inbox, daily. Get Versioning.
Login or Create Account to Comment
Login Create Account