Write maintainable CSS using SASS

by Dime Pashoski.

CSS is going through a revolution as it tries to keep pace with developments in browsers, mobile and apps. But even while it's getting a boost with some awesome new properties, it still has it's downfalls. That's why we love using SASS; it makes our lives much easier, and allow us to cut down the time we spend on front-end development and rapid prototyping.

SASS is short for Semantically Awesome Style Sheets and was developed initially by Hampton Catlin in 2006. It's a CSS preprocessor that allows you to write semantic and intelligent CSS, that is easy to maintain and later is compiled to valid minimized CSS.

There is a slight learning curve, but if you're a CSS veteran then it won't be a problem.

Why SASS?

SASS gives you everything you're missing in CSS, and even more. Some of the advantages of using SASS are:

  • Better syntax
  • Nested rules
  • Selector inheritance
  • Mixins & Expands for keeping your code DRY
  • Variables
  • Scalable & easy to maintain CSS

Setting up

You can run SASS in a lot of different ways and different development environments. At Siyelo we run it as a gem via the command line within our Rails/Sinatra projects, and it's as simple as:

gem install sass  

If you feel intimidated by using the terminal, you can try some of the available apps for running SASS:

There are even SASS plugins for Visual Studio, Wordpress & Grails you can use for an easy setup.

Syntax & Nested rules

SASS uses two different syntaxes - SASS and SCSS. There are some differences in the way you write, but both have the same super powers.

We'll start of with a simple example that will show you what's the differece between the two syntaxes, and how nesting of selectors work. Let's say you have a simple site navigation you want to style:

<nav id="main-nav">  
    <ul>
        <li><a href="home">Home</a></li>
        <li><a href="products">Products</a></li>
        <li><a href="about">About</a></li>
        <li><a href="contact">Contact</a></li>
    </ul>
</nav>  

Having plain HTML doesn't cut it, so you write some CSS to make it pretty:

#main-nav {
    background: #EEE;
}
#main-nav a {
    color: #4598e2;
    display: block;
    padding: 5px 10px;
    text-decoration: none;
}
#main-nav a:hover, #main-nav a:focus {
    color: #5739a3;
}

Simple CSS, easy to wite and understand, right? It could be much better with SASS or SCSS.

SASS

The SASS syntax was the original language, hence the name of the preprocessor. It practiced minimalism with strict indentation and no semicolumn or curly brackets.

Now let's go back to our example and see how it looks like in SASS:

#main-nav
    background: #EEE
    a
        color: #4598e2
        display: block
        padding: 5px 10px
        text-decoration: none
        &:hover, &:focus
            color: #5739a3

You will immediately notice that the curly brackets and the semi-columns are gone, and indentation plays a big role in defining parets and children. Just by nesting the anchor under the navigation ID you extend the path.

SCSS

SASS' rigid writing rules however prove to be problematic for some people, so SCSS came into play, or as some like to call it: CSS on steroids. It contained the same power under the hood as SASS, but practiced the same syntax as CSS. This means you could just copy/paste a chunk of CSS into it and it would work without complaints. On the other hand with the SASS syntax, first you need to convert the CSS to avoid breaking the compiled code.

This is the same example from above with using SCSS:

#main-nav {
    background: #EEE;
    a {
        color: #4598e2;
        display: block;
        padding: 5px 10px;
        text-decoration: none;
        &:hover, &:focus {
            color: #5739a3;
        }
    }
}

It's the same thing like SASS, only including the curly brackets and semi-columns, and it can drop the indentation rules (but nesting is still crucial!).

Comparison

Bottom line is that SCSS is forgiving to bad writing and works seamlessly with CSS, but SASS is cleaner, easier to maintain and keeps the curly brackets and semi-columns away.

You'll just end up using whatever is more comfortable for you and still get the same kick out of it.

Variables

One of the basic strenghts of Compass are defining variables. These can be used to reference things like HEX colors, font sizes, line-heights, etc. These are usually things that we tend to unify and reuse all around the site to achieve visual consistency across all pages.

In our example we use #4598e2 link color and #5739a3 when hovering. This will most likely be used on a lot of places and repeated many times. And what happens when we want to change that color? Mass replace the HEX in the entire project, something that can be harder than it sounds.

By using variables we can make this feel like a breeze. We simple take the two colors, and define them as variables. It looks something like this:

$link-color: #4598e2
$link-hover: #5739a3

and we can reference them in the SASS:

#main-nav
    background: #EEE
    a
        color: $link-color
        display: block
        padding: 5px 10px
        text-decoration: none
        &:hover, &:focus
            color: $link-hover

Now if we want to play with our colors, we can do it by tweaking the defined variables and the changes will be visible throughout the entire project.

Mixins

Mixins are arguably the most powerful feature of SASS. They allow you to define custom selectors that reference a set of CSS properties.

To see how it works let's go back to our simple navigation example. Our next goal would be to improve the styling some more by adding CSS3 border-radius.

We need to add this CSS to the code:

#main-nav {
    -moz-border-radius: 3px;
    -webkit-border-radius: 3px;
    -ms-border-radius: 3px;
    border-radius: 3px;
}

Here come the annoying vendor-specific CSS properties that require a lot of attention to achieve cross-browser compatibility and bloat our code. By using SASS we could easily define a mixin to replace that ugly code:

=border-radius($radius)
    -webkit-border-radius: $radius
    -moz-border-radius:    $radius
    -ms-border-radius:     $radius
    border-radius:         $radius

#main-nav
    +border-radius(3px)

Or this if we use SCSS:

@mixin border-radius($radius) {
    -webkit-border-radius: $radius;
    -moz-border-radius:    $radius;
    -ms-border-radius:     $radius;
    border-radius:         $radius;
}

#main-nav { @include border-radius(10px); }

This is what we call a mixin. It's a reference to a set of predefined CSS rules, using variables to define the parameters (px, em, etc).

Extend

This is a fairly new and very useful SASS feature, available since version 3. What it does is extends the CSS properties of an element by using already defined selector. It follows similar pattern as the mixins, in that it's useful for recyling code.

For example we need to define few different alert messages on our site:

.alert
    font-size: 12px
    padding: 5px

.error
    @extend .alert
    color: $red

.notice
    @extend .alert
    color: $blue

Mathematical operations

In SASS you can do math. You can do additions, substractions, multiplications and divisions. For example we're building some layout, and we need to define content and sidebar sections.

.wrapper
    width: 100%

.main
    width: 600px / 1000px * 100%

.sidebar
    width: 400px / 1000px * 100%

This will be converted to:

.wrapper { width: 100% }

.main { width: 60%; }

.sidebar { width: 40%; }

You can do the same with fonts and colors to define typographic rhytms or get more different shades of some color.

Extra boost

You can boost your front-end experience and cut down development time even more by using SASS frameworks like Compass, Bourbon and Susy. Why write custom mixins for CSS3 properties, when you can choose from a huge library that contain all the best practices in writing cross-browser compatible CSS. Not to mention that you can easily get rid off those pesky presentational classes that give your code Divitis.

Other popular tools, extensions & resources include:

Give it a go, and you'll never come back to writing plain CSS again.