Getting Started with Sass

Remember the invention of the font element? Yeah, me neither. But what a day that must have been! Suddenly we could break out of the sad world of Times New Roman and start using those other three fonts and an array of magical “web safe” colours.

Things have certainly come a long way since then. Many new advancements have come along to help us create beautiful websites. Most notable is the humble Cascading Style Sheet. I think we all take this for granted. Just think: we used to have to do image rollovers with JavaScript, magic and curse words!

But as websites and pages have become more complex, CSS quickly buckles under the weight. It’s still a thousand times better than tables for layout but it really hasn’t changed all that much…selectors, properties and values.

This is where CSS preprocessors come in. They add a new layer of awesome on top of a syntax we already know and love. There are many CSS preprocessors out there, but I’m going to focus on the one that captured my heart: Sass.

A Quick Definition

A CSS preprocessor is a bit of software that adds a nifty new feature-set to CSS  like variables, nesting and mixins. You write in a slightly modified CSS-like syntax which is then processed into plain-ol’-CSS. This processing can either happen on your development environment as you’re coding or as a part of your deployment process.

My prefered method—as I’m not a server nerd and get scared by deployment scripts—is to have my preprocessing done right in my development workflow. (More on this later.)

Why Sass

This is the big question—and there is no real answer. For me, Sass provides the right tools, syntax and extensions. Sass has a huge community behind it and is constantly growing and evolving. There are loads of excellent add-ons and extensions which make Sass even better. Sass also gives you two writing style options.

Sass Indented Syntax

This is like the crazy, wise uncle of CSS: quirky, kinda funny looking, but ultimately quite smart. This syntax looks nothing like CSS—the goal is brevity. Instead of brackets and semicolons, it uses the indentation of lines to specify blocks. Where you’d use a semicolon to separate statements, it uses new lines.

#main
  color: blue
  font-size: 0.3em

  a
    font:
      weight: bold
      family: serif
    &:hover
      background-color: #eee

.scss

.scss is essentially a subset of the CSS3 syntax. This means that every valid CSS3 stylesheet is valid.scss as well.

#main {
  color: blue;
  font-size: 0.3em;

  a {
    font: {
      weight: bold;
      family: serif;
    }
    &:hover {
      background-color: #eee;
    }
  }
}

This is my preferred syntax and what I’ll be using to show examples throughout this article. So without further ado, let’s get cracking.

Workflow and Tools

Workflow

There is a slight shift in paradigm required to get into the Sass way. The main point being that you will never ever edit or commit your .css files. The only way to change the CSS is through the .scss files. Once you save your .scss file, the magic of the preprocessor will convert it to regular CSS. The moment you start editing your .css files is the moment the sky starts to fill with black holes…

There are two common ways to roll the preprocessor into your workflow. The first is to do it at build time. This will require some setup on your development and live environments using a parser for the programming language you choose. Rails 3.1 and up ships with Sass. If you use PHP, .NET or Java you’re in luck, as there are ports for those platforms. You could also roll it into a GRUNT task to run the procressing on build.

If none of this makes sense to you don’t be afraid! The second option is much more front-end friendly: use a simple GUI on your development machine and compile as you go. You will need one of the following tools.

Tools

  • Compass.app

    This is a great multi-platform GUI which is simple and intuitive. It compiles Compass, which is a framework for Sass that I’ll get into later. Compass.app has the ability to hook into LiveReload too.

  • LiveReload

    This magical tool does a whole array of cool things, one of which is compiling Sass. LiveReload monitors changes in the file system. As soon as you save a file, it is preprocessed as needed, and the browser is refreshed. This is a great speedy kick to your web dev workflow. Currently available for $10 for Mac. There is an alpha version is available for Windows XP and up which is currently free.

  • CodeKit

    This is very similar to LiveReload but with a few more features—including script minification, image compression and code hinting. This is the software I’ve opted for and love dearly. It’s Mac only and available for $25. I recommend you download a trial—you’ll Add To Cart before you know it.

  • Mixture

    This is an up and coming tool that looks to have all the bells and whistles. It’s multi-platform and does a lot of very interesting stuff including boilerplating, image optimisation, one click publishing and many others. It looks to be in private beta at the moment but you can sign up to be notified when it’s good to go.

Let’s Start Coding, Already!

Nesting

This is probably the most fun but also the most dangerous part of Sass. Let’s consider the following two examples.

Example 1 — Good nesting

#navbar {
  width: 80%;
  height: 23px;

  ul { list-style-type: none; }
  li {
    float: left;
    a { font-weight: bold; }
  }
}

Example 2 — Bad nesting

div#main {
  #sidebar {
    #navbar {
      width: 80%;
      height: 23px;

      aside {
        div {
          ul { 
            list-style-type: none;

            li {
              float: left;
              a { 
                font-weight: bold;
              }
            }
          }
        }
      }
    }
  }
}

The reason Example 2 is bad is because the resulting CSS will have far too specific selectors.

div#main #sidebar #navbar {}
div#main #sidebar #navbar aside div ul {}
div#main #sidebar #navbar aside div ul li {}
div#main #sidebar #navbar aside div ul li a {}

Let’s all agree that’s a nightmare.

One of the guiding principles of modern CSS should be the principle of modular code—that is to say, bits of code that you can reuse without having to rely on the structure of your markup. For more information on this idea, look into OOCSS and SMACSS.

There’s a de facto rule called The Inception Rule that simply states you should never nest more than four selectors deep.

Variables

$site_max_width: 960px;
$font_color: $333;
$link_color: $00c;
$font_family: Arial, sans-serif;
$font_size: 16px;
$line_height: percentage(20px / $font_size);

body {
  color: $font_color;
  font {
    size: $font_size;
    family: $font_family;
  }
  line-height: $line_height;
}

#main {
  width: 100%;
  max-width: $site_max_width;
}

We’re all familiar with variables and use them in our JavaScript, etc. This is the exact same idea, but with CSS. Now, when a client asks you change that blue to a slightly more greeny-blue (with more pop), you can simply go to your variables and update that one instance. You can also use built-in Sass functions and operators as well as reference other variables in the declarations.

Functions and Operators

Like any programming language, Sass comes with a suite of functions and standard operators. There are many fnctions that will help you deal with number, text and colours. And all numbers (including those with units) have all the math operators you’ll ever need: +, -, *, / and %.

Have a look at the documentation to see the list of goodness available.

Mixins

Mixins are one of the most powerful parts of Sass and really allow you to get creative. A mixin is a collection of of re-usable styles, properties and selectors. You could think of a mixin as a macro or snippet for regular re-use.

A good example of a mixin is one to handle those annoying vendor prefixes:

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

Or for hiding text (often used with image replacement techniques):

@mixin hide-text {
  font: 0/0 a;
  color: transparent;
  text-shadow: none;
  background-color: transparent;
  border: 0;
}

Needless to say, you’ll be spending a lot of time coming up with your own personal arsenal of mixins to use on all your projects.

Your First Sass Project

The beauty of using Sass is that you can make as many small .scss files as you see fit because they will all be combined into one master .css file during the preprocessing stage. Consider the following style.scss file:

@import "global/mixins";
@import "global/variables";
@import "global/normalize";

@import "content/links";
@import "content/lists";
@import "content/mediaObjects";
@import "content/panels";
@import "content/spacingOverrides";
@import "content/typography";
@import "content/textUtilities";

@import "layout/border";
@import "layout/grid";
@import "layout/scaffolding";

@import "navigation/breadcrumbs";
@import "navigation/master";
@import "navigation/leftnav";
@import "navigation/topnav";
@import "navigation/pagination";
@import "navigation/tabs";
@import "navigation/footer";

@import "forms/buttons";
@import "forms/forms";

@import "tables/tables";
@import "tables/forum";

Each of those @import statements includes a new .scss file. When naming these component .scss files, make sure you use an underscore (_) character at the start of the file name. Example: _variables.scss, _normalize.scss. The Sass compiler will interpret these files as snippets and won’t actually preprocess them individually. Only the files you want the preprocessor to compile should be named without an underscore, e.g. style.scss, special-page-override.scss.

When you import the snippet files into your main style file there’s no need to include the underscore of the file extension—Sass knows you’re working with .scss files.

As you might have guessed, it makes total sense to organize your Sass files into folders for easy separation of logic and structure—you can get as complex as you need, but remember that everything you do will need to make some sort of sense six months down the line when you come back to modify stuff. Don’t make it more difficult for your future self (or a different developer).

Extending Sass

There are a number of excellent add-ons or frameworks built on top of Sass. But I’m going to talk about just one—the almighty Compass.

Compass

Working with Sass and Compass makes me smile. In actual fact, I’m smiling as I write about Compass and I’m hoping you will be too when you’re done with this article. Compass is a full-featured framework built on top of Sass that includes reusable patterns, sprite generation, typographic rhythms and all the CSS3 mixins you’ll ever need.

The compiling software I mentioned above will all be able to deal with Compass, so getting started with Compass is a very simple process. Create a file in the root of your web project called config.rb—this file will tell Sass that you’ll be using Compass for your project. The code below is the very minimun you require to get Compass going.

# Require any additional Compass plugins here.

# Set this to the root of your project when deployed:
http_path = "/"
css_dir = "css"
sass_dir = .scss"
images_dir = "images"
javascripts_dir = "js"
fonts_dir = "fonts"

output_style = :expanded
environment = :development

Check out the documentation for other options you could set.

The next step is to import Compass into your main style file. You can either import the entire Compass framework or parts of it as and when you need them.

@import "compass";

@import "global/mixins";
[...]

Or…

@import "compass/utilities";
@import "compass/css3";
@import "compass/typography/vertical_rhythm";

@import "global/mixins";
[...]

I could blow another 5,000 words waxing lyrical about Compass as there is so much to it, but instead I’m going to dig into one of the most powerful features to grace our text editors since float: left;

Sprite Generation

Sprites have quickly become the default standard to delivering images on the web using CSS. If you’re unfamiliar with the concept then I suggest you have a quick read. They are great for the web but they can very quickly become a pain in the ass! I often find I have to update my sprites as a project progresses and this becomes a chore as you not only have to update your main sprite sheet but you also have to update your CSS (and potentially HTML, too).

Over the years, there have been some great tools introduced to help make this process easier but nothing has quite sat right with me. Until now.

The main idea here is that you should create single images as you would have in the olden days. The important thing is to keep your images organised into folders, as illustrated below.


Screenshot of organised image folder

The next step is to include the required compass mixins and utils and import your images. In the following examples, I’ll be illustrating how this might work when using the images/icons folder.

// include the compass spite utility if not already included
@import "compass/utilities/sprites";

// import your images
// note: compass already knows my images live in the /images/ folder
@import "icons/*png";

// automagically generate class names
@include all-icons-sprites;

I’ll walk you through that. The first import is importing the correct Compass sprite utils. The next import is telling Compass where the images are that you’d like to use as a sprite. The include line is where some magic occurs. This line will auto-generate a bunch of class names based on the name of the image folder and the name of the PNGs therein. The generated CSS is below:

.icons-actions-add-mini,
.icons-actions-delete-mini,
[...]
.icons-multimedia-camera {
  background: url('/images/icons-s34fe0604ab.png') no-repeat;
}

.icons-actions-add-mini {background-position: 0 0;}
.icons-actions-delete-mini {background-position: 0 -16px;}
[...]
.icons-multimedia-camera { background-position: 0 -96; }

At this point you could just walk away and happily use those generated classes wherever you wanted. Job done. Thanks, Compass!

However, I often find I’ll need to add my own class names—based on nested elements, perhaps. No worries. Compass allows us to do this.

Note: With the following examples, the param passed into those icons-sprite-*() utils are the names of the .png files in your images/icons folder.

@import "icons/*.png";

.actions {
  .add    { @include icons-sprite(actions-add-mini); }
  .delete { @include icons-sprite(actions-delete-mini); }
}

.contact {
  .mail  { @include icons-sprite(contact-mail); }
  .phone { @include icons-sprite(contact-phone); }
}

.some-random-class-name { @include icons-sprite(hardware-television); }

There quite a few other customisations Compass gives you. This next example is one I find myself using quite a bit.

// making use of width/height magic selectors
.icon-giant-killer-bear {
  $width: icons-sprite-width(giant-killer-bear);
  $height: icons-sprite-height(giant-killer-bear);
  @include icons-sprite(giant-killer-bear);
  @include size($width, $height);
  margin: 0 4px 0 0;
  vertical-align: text-bottom;
}

The above example illustrates how easy it is to get the image dimensions of a particular image from your sprite. Couldn’t be any easier!

I haven’t dug too deeply into all of the sprite utils but check the Compass website for the full sprite documentation as I’m sure there are a load of other awesome things out there.

To Sum Up

There is an exciting new world of front-end code out there and this is just a very small part of it. Start using Sass now! It’s made my code writing more efficient and it’s made writing CSS a lot more enjoyable. I’m no expert when it comes to this stuff—I’m still learning new awesome things every day, so if you find any errors or omissions please let me know by shouting at me in the comments.

If you’re in Australia during March, you can also catch me talking about Sass in a series of workshops, together with Russ Weakley on Responsive Web Design.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Neil L

    Very interesting read, and I’m keen to delve in to CSS pre processors… The part I find tricky to get my head round is using them within a team… What are some useful tips for helping with that, then I can start coaxing my colleagues into using them too!

    • http://dontcom.com Darren Wood

      Introducing any new technology into a team comes with teething issues. My advice is to educate and evangelise the benefits of using Sass. The moment a CSS or front-end developer uses Sass and sees the upsides there will be no turning back.

      Make sure you choose the right compiling tools for your work environment. Our office uses Macs so CodeKit works very well for us. If you’re a multi-platform studio then choose something like Compass.app which will run on Windows, Mac and Linux. The key is to make the new workflow easy and fun.

      Good luck with convincing your team, I’m sure it’ll be a piece of cake!

      • Neil

        Thanks Darren… Is it straightforward keeping all the files in sync collaboratively? I guess it just comes down to making sure the pre and post compiled files are always uploaded to avoid issues?

      • http://dontcom.com Darren Wood

        Neil, your source control system should take care of that for you.

  • http://sassmeister.com Jed Foster

    Check out http://sassmeister.com to play with Sass in the browser. Experiment with both the indented syntax and SCSS, as well as nearly 20 Compass extensions and see the CSS output in real time.

    • http://dontcom.com Darren Wood

      This is an enormously useful tool! Thanks for your work on that :) It’s great to have a place to quickly try out some Sass.

  • http://grantpalin.com Grant Palin

    “Remember the invention of the font element?” — maybe that should be invasion? :)

    Sass is really nifty, it’s something I’m experimenting with off and on lately. I’ve been collecting links to useful information on the subject. It surprises me how much Sass offers that seem to me like they should be part of CSS itself – variables and nesting, at the least!

    I do quite like the ability to split the styles into component files, with everything in its place, to be compiled into a master resultant CSS file.

  • http://geertdedeckere.be/ Geert De Deckere

    Don’t forget about Bourbon, a simple and lightweight mixin library for Sass.

  • Michael Morris

    “Instead of brackets and semicolons, it uses the indentation of lines to specify blocks.”

    No. Hell No. I’ve had enough bad experiences with Python and YAML files to know that while this might sound like a good idea, in practice it’s a nightmare. I’ll stick to LESS thank you.

    • Chris Emerson

      Agreed – significant whitespace is a terrible idea

    • http://dontcom.com Darren Wood

      You don’t need to use the indented syntax. There’s the scss syntax which is just like CSS and LESS. And in my opinion, the far superior syntax. Give it another look—I think you might like it :)

  • Robert

    Lovely article Darren. One thing though, you’re writing “.scss is essentially a subset of the CSS3 syntax.”. But in fact it is a superset of CSS3, that’s why you can just rename your regular plain old .css files to .scss and they will still compile without a hitch.
    (Although manually converting to real .scss, or even converting through the sass-convert command would be the better option.)

  • Chris Emerson

    The thing that worries me is that debugging would become very difficult. Firebug tells me what line of css a certain declaration is made on, yet with this I’d have no idea.

  • Jonathan Thomas

    Hi Darren,

    Would you suggest checking the SCSS file (before compilation) into git or the post-processed CSS file into git?

    Many thanks

    • http://dontcom.com Darren Wood

      I would check the .scss files in as those are the actual source files—i.e. the ones you’ll be editing.