Four months ago I presented "Quickstart to Sass/Less.js CSS" at the Jersey Shore Tech meetup and it's about time to share my thoughts. Although my talk covered both Sass and Less.js today we will only cover Sass as it's the tool I use more often. If you're interested in Less.js I did recently post one thing about Less.js.

To learn more about the Sass project go check out the project site and make sure to follow TheSassWay and Compass on Twitter to keep up-to-date with Sass and Compass news. We'll dicsuss Compass in a bit.

Overview of Sass

Sass is an extension of CSS, and as its tagline says, it "... makes CSS fun again".

But what does that really mean? It means Sass and provides additional features on top of CSS helping organize your CSS into cleaner, more manageable code and promotes reuse through @mixins, @extends, @includes. Together these help reinforce the DRY principle. Sass executes these features by compiling your source .scss/.Sass files and producing valid .css files.

Compilation huh what?

The thought of compilation may be foreign to you, and if it is then here's a brief description as to why it needs to happen.

As we discussed, Sass adds extensions to CSS. Something as simple as a variable is not known to CSS. In Sass it's as simple as...

//source app.scss file
$button-buy-color: #ff0000;

Then for all the styles you want to reference $button-buy-color. Here's a very basic example:

// source app.scss file
#sale button
  background-color: $button-buy-color;

#special button
  background-color: $button-buy-color;

To get the above to render the correct CSS you need to let Sass compile it using the `sass app.scss app.css'. command. The compilation would generate:

// resulting app.css file
#sale button
  background-color: #ff0000;

#special button
  background-color: #ff0000;

The end result of Sass compiling your .scss file is a .css file. In the above example if we wanted to change the color for all "buy buttons" we would just have to change the value in one location.

Actually, another way to think about compilation — you could create a valid CSS file, using no Sass features, but save your file with the .scss extension and it would still be a valid Sass file when compiled. You don't need to use features of Sass in your .scss files for them to compile correctly, but if you're doing that then just create .css files.

So, Sass files must be compiled prior to deployment. You can compile them on your local machine, as part of your build/deploy process, etc. Referencing a .scss file in the of you HTML templates will do you no good. This is incorrect...

<link rel="stylesheet" href="/css/whatever.scss" media="screen" />

The end the goal we're all aiming for is to produce quality CSS and Sass helps you get there and beyond. It just may take one additional step to get you there... compilation.

Sass Features

What are these killer features? The ones I use most often are mixins, functions(), variables, nested rules various @-rules and directives, parent selectors and sometimes operations. We'll discuss some of these in a bit along with some code examples, but before we go any further serving up pints of the Sass Cool Aid let's discuss why you may not want to use Sass, and some of the reasons I initially didn't buy into it.

Why not Sass?

For noobs being introduced to Sass I can easily see why you might think this is an over-engineering for something as simple as CSS. Why add a compilation step to render CSS? This isn't server side code! The argument has some weight, but I'd argue you can't really begin to grasp the utility of these tools until you get your hands dirty.

My initial introduction to these CSS extensions was actually CleverCSS. This and my curiosity in similar solutions eventually led me over to Sass, which at the time only offered the indented syntax. As a reminder the indented syntax looks like this...

@mixin table-base
  text-align: center
  font-weight: bold
  td, th
  padding: 2px

No semicolons? White-space sensitivity in CSS!? What is this "@mixin" directive? I was immediately turned off. Here's why...

First, Sass's original, unindented syntax was a bit too foreign to me. It's just CSS, why are we breaking convention? If I'm going to use this or my team is going to use this, or a new hire is going to use this, then it should be familiar. The updated "Sassy" syntax resolves this concern.

Next, the idea of a pseudo programming language intertwined with CSS seemed over-engineered. Mixins, variable, control directives, oh my! Such things aren't meant for CSS! CSS is about style, not programing. Right? Boy was I wrong. These "complexities", as I initially viewed them, are powerful features for making CSS organized, reusable, concise, and in the end... simple.

Then there's the introduction to yet another dependency... Ruby. There's no way around this one. You will need to add it to your stack to compile your Sass source files.

Next, there's the new step/disruption to your existing workflow - compilation. This one is hard to avoid as well. You can't just edit your css file and view the resulting CSS changes locally without compilation. You have to edit the .scss and then compile it. It's not as difficult as it sounds though, and Sass comes with a handy --watch option which makes this esentially painless. Again, this is a trade-off I'm willing to make.

Finally, probably the largest obstacle with these CSS extentions is debugging. Sass itself provides a terrific debugger — if there are syntax errors with your .sass/.scss files then Sass will display what file and line raised the exception. This is great. But if your trying to figure out why something isn't displaying in the browser correctly then the features offered by Sass (i.e. mixins, includes, extends, etc) come at the expense of the pre-processing compilation of your Sass source files, and result in a less forgiving debugging process. For example, a style defined on line #32 of one of your .scss files may render on line #153 of a resulting .css file. This one hurts the most.

All of the above and you still think we need Sass? We've gone so long without these features why do we need them now? Let's be honest we all know you don't need them.

Nathan Borror, creator of Readernaut, shares some of my same concerns discussed above. His post from 2009, "Sass isn't for me" is a great critique especially for the comments discussion. Some of his issues have been resolved since the post (sassy syntax and whitespace sensitivity, for example). Nathan later posted "Less.js is more", a follow up where he details his Less.js impressions. Sadly both of these posts no longer exist. I followed up with Nathan recently and he no longer uses either much these days. He added, "I really do respect and admire what people are trying to do in this space and it's up to the developer to decide what's right for their situation. I kind of regret the two blog posts because, while I tried to be constructive and spark an intelligent discussion, it ultimately comes down to deciding which tool helps make your product great."

I couldn't agree more with Nathan.

So Why Sass then?

For me, Sass's features provide a more reusable and more easily maintainable code base and therefore the benefits outweight any of the above changes to my process.

My favorites features of Sass is the @mixin, arguably the most powerful feature. It allows the developer to encapsulate display code into reusable components, keeping your code concise, reusable, and easily maintained. Here's a basic example. The below mixin provides base functionality for a standard message UI element on a website.

@mixin user_message($bgcolor: #CCC, $color: #FFF, $border: left){
  padding: 20px;
  background-color: $bgcolor;
  border-#{$border}: solid 2px darken($bgcolor, 40%); 
  color: $color;
  margin-bottom: 10px

The above is a Sass mixin with a bunch of Sass features employed. It uses arguments ($bgcolor: #CCC, $color: #FFF, $border: left) with default values to allow the developer to specify various properties. If you notice border-#{$border}: I'm using interpolation to inject the variable value into the style definition. I'm also using darken() which is an HSL function to dynamically set the color of the border I specify.

I can then implement the below for 3 various message elements (server error is a bit contrived). Here's my app.scss snippet:

@import "message";

// this uses the default arg values

  @include user_message();

//this overrides all the args

  @include user_message(#F5F5F5, #FF0000, right);

// this extends the above error style with some additions
  @extend .error;
  font-size: 220%;
  border: solid 5px red;

In the above I've used the @import directive, the @include directive, referenced the user_message mixin, and the @extend directive. These are the core methods used in reusing code throughot your project. Read the docs to get more familiar with them, or better yet try them out yourself and break things to learn.

Back to the code. The above results in this after the app.scss is compiled:

.message {
  padding: 20px;
  background-color: #cccccc;
  border-left: solid 2px #666666;
  color: white;
  margin-bottom: 10px;

.error, .server-error {
  padding: 20px;
  background-color: #cccccc;
  border-left: solid 2px #666666;
  color: red;
  margin-bottom: 10px;

.server-error {
  font-size: 220%;
  border: solid 5px red;

As you can see my source .scss file is more concise. I've created a reusable message mixin. From there I've reused this mixin on the .message and .error classes and then again on .server-error where I've gone and extended the .error class which is reusing the message mixin above. And if I ever want to change the structure or style of all my user message UI elements on my site I just update the user_message @mixin in one place.

Let's take it a bit further and review the popular rounded corners example by making it reusable and easily maintainable.

Here's what it would take to style a rounded corners class in CSS today:

  -webkit-border-top-left-radius: 5px;
  -webkit-border-top-right-radius: 5px;
  -webkit-border-bottom-right-radius: 5px;
  -webkit-border-bottom-left-radius: 5px;
  -moz-border-radius-topleft: 5px;
  -moz-border-radius-topright: 5px;
  -moz-border-radius-bottomright: 5px;
  -moz-border-radius-bottomleft: 5px;
  border-top-left-radius: 5px;
  border-top-right-radius: 5px;
  border-bottom-right-radius: 5px;
  border-bottom-left-radius: 5px;

Writing this often becomes redundant and time consuming. Dan Cederholm, author of CSS3 for Web Designers recently tweeted, "Crafting Sass mixins for oft-used CSS3 stacks. The time-saver of all time-savers. Native variable/mixin suport for CSS4 please thanks.""

I agree! Using Sass we can create one mixin and then reuse this as often as we like. Then, if we need to add a change to support another browser, for example, we just edit this one mixin and the rest of our code is updated as well. Here's the mixin and Sass implementation that also provides arguments for specifying the corner radius values:

@mixin multi-rounded-corners($topLeft: 5px, $topRight: 5px, $bottomRight: 5px, $bottomLeft: 5px) {
  -webkit-border-top-left-radius: $topLeft;
  -webkit-border-top-right-radius: $topRight;
  -webkit-border-bottom-right-radius: $bottomRight;
  -webkit-border-bottom-left-radius: $bottomLeft;
  -moz-border-radius-topleft: $topLeft;
  -moz-border-radius-topright: $topRight;
  -moz-border-radius-bottomright: $bottomRight;
  -moz-border-radius-bottomleft: $bottomLeft;
  border-top-left-radius: $topLeft;
  border-top-right-radius: $topRight;
  border-bottom-right-radius: $bottomRight;
  border-bottom-left-radius: $bottomLeft;

Hey, why don't we make our message element have rounded corners as well! To reuse the @multi-rounded-corners in our application's .scss file we just add one line to reference the multi-rounded-corners() mixin.

@import "message";

  @include user_message();
  @include multi-rounded-corners();

And whala! We now have a "success" style that reuses both our @user_message and @multi-rounded-corners mixins. Code is now organized. Simpler to read. Simpler to update. Go take that long lunch break.

Learning Sass

The first thing you want to know is how to use this thing. The official Sass tutorial is a great place to start.

If you like screencasts the people over at ThinkVitamin are producing an entire series on the subject. You can watch the first episode Sass Introduction for free.

I highly recommend watching the terrific screencast Kicking Ass and Taking names with Sass and Compass. Seriously, make sure you watch this as Nathan created a very well produced screencast with a handful of great examples and code review. We haven't discussed Compass yet, we do briefly below, but I suggest familiarizing yourself with in your next step along the SassWay.

So there's plenty information out there already if you're looking to learn, and more and more being published each day. Check out Forrst and Github for more Sass examples.

Is Sass a Framework?

I often hear this question asked. Sass is not a framework. It's an extension of CSS. Sass offers the interface to execute these extensions. Compass is a framework. From their docs...

"Compass, at its heart, is a framework upon which Sass-based stylesheet frameworks are built. It provides the tools for building, installing and using reusable stylesheets that provide anything from full-fledged layout frameworks to designs for widgets or even full page designs. All using the power of Sass to keep the semantic meaning of the html pages clear and free of design details."

For those familiar with Django or Rails, here's a good analogy (via Idan Gazit) between Sass and Compass — "Compass is the Django, Sass is the Python or Compass is the Rails, Sass is the Ruby."

Just like the above, Python and Ruby are the core languages that make Django and Rails frameworks possible. You can write Sass without Compass, but you can't build a Compass extension without Sass. And just like these web frameworks Compass also provides additional utility, conventions, best practices, documentation, community contributed libraries, and is continuously developed and tested (Go fork it on Github now!). For example, take a look at Compass core for various helpers/utilities. Checkout Compass blueprint for your layout needs. Want some fancy buttons? You can install the fancy buttons Compass plugin the community created, or if you want to get on the responsive design train hook the Less Framework (not Less.js) check out compass-less-plugin. There's also Idan Gazit's Sinter for a minimal approach to responsive design for Compass. So you get the idea - the open source community is contributing and building a community of this plugins.

Diving full into Compass and all its features requires an additional, lengthier discussion (for example a Compass extension can include JS files and Images). Make sure to check it out though because it's extremely powerful.


The above code snippets are very basic examples but I hope communicate the concepts of how and why you would want to include Sass in your projects. One large project that employs Sass and makes its code freely available is Sencha Touch. If you want to take a look at how a large, publicy available project integrates Sass then Sencha Touch is a good place to start. In fact, they recently published an advanced Sass implementation Touch Charts Styling which makes for a good read just to see how far you can push Sass with a little creativity. If you know of others please drop them in the comments below.

As I mentioned, you don't begin to appreciated the utility of Sass until you use Sass in your projects. The project site and documentation for both Sass and Compass are terrific which lessens the barrier to entry. And although there are some learning curves along the way, once you get passed those little bumps, just like many others have already, you'll find yourself not wanting to look back.

Before we leave, Sass 3.0 introduced a new command line utility sass-convert which makes converting existing CSS to Sass a breeze, even converting some of your existing styles into Sass compliant nested rules where appropriate. Someone also created a web UI to do this over at CSS 2 Sass. So what are you waiting for?