A Simple And Easy Guide To Understand Sass

A while ago Thoriq Firdaus wrote a great article about getting started with Sass which showed you how to install and use this highly useful CSS preprocessor language (you might want to check it out, you know, to get started).

In this article I thought I’d give you a bit more insight into what you can do with Sass and how developers use it every day to create better and more modular CSS code. Skip ahead to the section you want:

Tools Of The Trade

Thoriq showed you how you can use Sass from the command line using the sass --watch command.

If you prefer GUI tools, you can go with my personal favourite app, Codekit, a web developer tool for compiling Sass, concatenating, autoprefixing and much more. Prepros is another very capable application which can be used on all systems. Both are paid applications but are well worth it if you’ll be using them in the long run.

If you just want to try out Sass without paying for anything you can use the terminal, or Koala (here’s our review), a free cross-platform feature-rich app, which can hold its ground against premium counterparts.

Variables

One of the first things you’ll need to wrap your head around is variables. If you come from a PHP or other similar coding language background this will be second nature to you. Variables are for storing bits and pieces of reusable information, like a color value for example:

$primary_color: #666666;

.button {
    color: $primary_color;
}

.important {
    color: $primary_color;
}

This may not seem that useful here, but imagine having 3,000 lines of code. If your color scheme changes you would need to replace each color value in CSS. With Sass you can just modify the value of the $primary_color variable and be done with it.

Variables are used for storing font names, sizes, colors and a host of other information. For larger projects it may we worth extracting all your variables into a separate file (we’ll take a look at how this is done soon). What this allows you to do is recolor your whole project and change fonts and other key aspects without ever touching actual CSS rules. All you need to do is modify some variables.

Nesting

Another basic feature Sass gives you is the ability to nest rules. Let’s assume that you’re building a navigation menu. You have a nav element which contains an unordered list, list items and links. In CSS you may do something like this:

#header nav {
    /* Rules for the nav area */
}

#header nav ul {
    /* Rules for the menu */
}

#header nav li {
    /* Rules for list items */
}

#header nav a {
    /* Rules for links */
}

In the selectors, we are repeating ourselves a lot. If elements have common roots, we can use nesting to write our rules in a much cleaner way.

Here’s how the above code could look in Sass:

#header {
    nav {
        /* Rules for the nav area */
    }

    ul {
        /* Rules for the menu */
    }

    li {
        /* Rules for list items */
    }

    a {
        /* Rules for links */
    }
}

Nesting is extremely useful because it makes stylesheets (a lot) more readable. By using nesting together with proper indentation you can achieve highly legible code structures, even if you have a fair amount of code.

One drawback of nesting is that it can lead to unnecessary specificity. In the example above I’ve refered to links with #header nav a. You could also use #header nav ul li a which would probably be too much.

In Sass, it is much easier to be very specific since all you need to do is nest your rules. The following is far less readable and quite specific.

#header {
    nav {
        /* Rules for the nav area */
        ul {
            /* Rules for the menu */
            li {
                /* Rules for list items */
                a {
                    /* Rules for links */
                }
            }
        }
    }
}

Extending Rulesets

Extending will be familiar if you’ve working with object oriented languages. It is best understood through an example, let’s create 3 buttons which are slight variations of each other.

.button {
    display: inline-block;
    color: #000;
    background: #333;
    border-radius:4px;
    padding:8px 11px;
}

.button-primary {
    @extend .button;
    background: #0091C2
}

.button-small {
    @extend .button;
    font-size:0.9em;
    padding:3px 8px;
}

The .button-primary and .button-small classes all extend the .button class which means that they take on all its properties and then define their own.

This is immensely useful in many situations where variations of an element can be used. Messages (alert / success / error), buttons (colors, sizes), menu types and so on could all use the extending functionality for great CSS efficiency.

One caveat of extends is that they won’t work in media queries as you would expect. This is a bit more advanced but you can read all about this behavior in Understanding Placeholder Selectors – placeholder selectors are special kind of extend which we’ll talk about soon.

Mixins

Mixins are another favorite feature of preprocessor users. Mixins are reusable rulesets – perfect for vendor-specific rules or for shorthanding long CSS rules.

How about creating a transition rule for hover elements:

@mixing hover-effect {
    -webkit-transition: background-color 200ms;
    -moz-transition: background-color 200ms;
    -o-transition: background-color 200ms;
    transition: background-color 200ms;
}

a {
    @include hover-effect;
}

.button {
    @include hover-effect;
}

Mixins also allow you to use variables to define the values within the mixin. We could rewrite the example above to give us control over the exact time of the transition. We may want buttons to transition a tiny bit slower for example.

@mixin hover-effect( $speed ) {
    -webkit-transition: background-color $speed;
    -moz-transition: background-color $speed;
    -o-transition: background-color $speed;
    transition: background-color $speed;
}

a {
    @include hover-effect(200ms);
}

.button {
    @include hover-effect(300ms);
}

Placeholder Selectors

Placeholder selectors were introduced with Sass 3.2 and solved a problem which could cause a bit of bloat in your generated CSS code. Take a look at this code which creates error messages:

.message {
    font-size:1.1em;
    padding:11px;
    border-width:1px;
    border-style:solid;
}

.message-danger {
    @extend .message;
    background: #C20030;
    color:#fff;
    border-color: #A8002A;
}

.message-success {
    @extend .message;
    background: #7EA800;
    color:#fff;
    border-color: #6B8F00;
}

It is most likely that the message class will never be used in our HTML: it has been created to be extended, not used as is. This causes a little bit of bloat in your generated CSS. To make your code more efficient you can use the placeholder selector which is indicated with a percentage sign:

%message {
    font-size:1.1em;
    padding:11px;
    border-width:1px;
    border-style:solid;
}

.message-danger {
    @extend %button;
    background: #C20030;
    color:#fff;
    border-color: #A8002A;
}

.message-success {
    @extend %button;
    background: #7EA800;
    color:#fff;
    border-color: #6D9700;
}

At this stage you may be wondering what the difference between extends and mixins are. If you use placeholders they behave like a parameter-less mixin. This is true, but the output in CSS differs. The difference is that mixins duplicate rules while placeholders will make sure that the same rules share selectors, resulting in less CSS in the end.

Operations

It’s hard to resist the pun here, but I’ll refrain from any medical jokes for now. Operators allow you to do some math in your CSS code and can be pretty darn helpful. The example in the Sass guide is perfect for showcasing this:

.container { width: 100%; }

article {
  float: left;
  width: 600px / 960px * 100%;
}

aside {
  float: right;
  width: 300px / 960px * 100%;
}

The example above creates a 960px based grid system with minimum hassle. It will compile down nicely to the following CSS:

.container {
  width: 100%;
}

article {
  float: left;
  width: 62.5%;
}

aside {
  float: right;
  width: 31.25%;
}

One great use I find for operations is to actually mix colors. If you take a look at the success message Sass above it’s not clear that the color of the background and the border have some sort of relationship. By subtracting a shade of gray we can darken the color, making the relationship visible:

$primary: #7EA800;

.message-success {
    @extend %button;
    background: $primary;
    color:#fff;
    border-color: $primary - #111;
}

The lighter the subtracted color, the darker the resulting shade will be. The lighter the added color, the lighter the resulting shade.

Functions

There are a great number of functions to use: Number functions, string functions, list functions, color functions and more. Take a look at the long list in the developer documentation. I’ll take a look at a couple here just to show you how they work.

The lighten and darken function can be used to change the lightness of a color. This is better than subtracting shades, it makes everything even more modular and obvious. Take a look at our previous example using the darkening function.

$primary: #7EA800;

.message-success {
    @extend %button;
    background: $primary;
    color:#fff;
    border-color: darken( $primary, 5 );
}

The second argument of the function is the percentage of darkening required. All functions have parameters; take a look at the documentation to see what they are! Here are a few other self-explanatory color functions: desaturate, saturate, invert, grayscale.

The ceil function, just like in PHP, returns a number rounded to the next whole number. This can be used when calculating column widths or if you don’t want to use a lot of decimal places in the final CSS.

.title {
    font-size: ceil( $heading_size * 1.3314 );
}

Overview

The features in Sass give us great power to write better CSS with less effort. The proper use of mixins, extends, functions and variables will make our stylesheets more maintainable, more legible and easier to write.

If you’re interested in another similar CSS preprocessor I suggest taking a look at LESS (or check out our beginner’s guide) – the underlying principal is much the same!