The Sass Way (And Other Thoughts on Development)

As the line between designer and developer is increasingly blurred, we are required to meander back and forth between the various smaller roles and requirements. This brings on an interesting dilemma of keeping up with the constant waves of new techniques and requirements coming from the dev world.

Design is design: the fundamentals of design are universal, meaning we can apply Dieter Rams' 10 Principles for Good Design -- arguably the epitome of design theory -- to all forms of design and (with minor exceptions) can create truly beautiful and accessible products.

Development, on the other hand, is constantly changing due to a variety of reasons, requiring us to adapt and evolve. In many ways, we get to change the landscape and create as we go, which is both exciting and frightening. As new technologies come and go, so do the ideas that accompany them. Ideas eventually progress into products or services or style guides, and in turn develop into standards.

Sass is currently on this path, and my bet is we will see it set as a standard very soon.

An Introduction to Sass

Sass (not SASS or S.a.s.s.) is a CSS preprocessor that adds some major bonuses to vanilla CSS, such as nesting, variables, mixins, and extensions. At first glance, Sass (.scss) looks very similar to standard stylesheets (.css), which is to be expected: Sass isn't a whole new programming language, but rather an extension and improvement of an existing language. For example…

$colour_black: #140f1c;

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

.example-block {
    width: 20em;
    background: $colour_black;
    @include corners(.2em);
        p {
           font-size: 1.2em;
        }
}

is translated into…

.example-block {
    width: 20em;
    background: #140f1c;
    -webkit-border-radius: .2em;
       -moz-border-radius: .2em;
        -ms-border-radius: .2em;
         -o-border-radius: .2em;
            border-radius: .2em;
}
.example-block p {
    font-size: 1.2em;
}

As you can see, they are similar, and even if you have never seen a .scss file before you can certainly follow along. You may be thinking, "You just doubled your code compared to what is outputted, why would I do this?" This example is small, so let's explore some of Sass's more useful functions and how they can facilitate code on a larger scale.

Nesting

Nesting in Sass allows for CSS selectors to "embed" themselves into parent selectors, similar to how HTML works. This is useful because it presents a more logical approach to authorship while also reducing the amount of code written. A fairly common navigation, for example, is a nav, a ul, and its li links.

<nav>
    <ul>
        <li><a href="#">Link</a></li>
        <li><a href="#">Link</a></li>
        <li><a href="#">Link</a></li>
    </ul>
</nav>

Therefore, we can use the same logical approach and nest our .scss in the same manner…

nav
    background: black;
        ul {
            float: right;
            width: 10em;
                li {
                    float: left;
                    display: block;
                    padding-left: 1em;
                        a {
                            border-bottom: 1px solid blue;
                        }
                }
        }
}

…which spits out…

nav
    background: black;
}
nav ul {
    float: right;
    width: 10em;
}
nav ul li {
    float: left;
    display: block;
    padding-left: 1em;
}
nav ul li a {
    border-bottom: 1px solid blue;
}

Nesting is incredibly useful, but it is important to remember not to go overboard. As mentioned before, Sass is not its own language, so we still need to think about the output; it is very easy to nest all the things and end up with incredibly specific CSS. I have a general rule of going no more than four levels deep (sometimes five, depending on the context). Use your knowledge of basic CSS etiquette, SMACSS, and/or OOCSS.

Variables

With plain ol' CSS, making site-wide changes can be a hassle (depending on how your code is written). For example, you may have a consistent colour throughout the site: your body links, pull quotes, and emphasis boxes are all#d91c0e, but a decision has been made to change it to#0e6dd9. Instead of going through and replacing every instance of#d91c0e in your stylesheet, you could simply make the change once and have it reflected everywhere.

$font_sans: "Avenir", "Helvetica Neue", sans-serif;
$colour_blue: #06c;

.example {
    font-family: $font_sans;
    color: $colour_blue;
}

becomes…

.example-2 {
    font-family: "Avenir", "Helvetica Neue", sans-serif;
    color: #06c;
}

Reuse variables for quick changes and consistency throughout projects.

Mixins

Mixins work generally in the same vein as variables, except with a lot more oomph. Certain chunks of CSS can be quite wearisome to write and reuse repeatedly in a stylesheet. From the official Sass doc, "A mixin lets you make groups of CSS declarations that you want to reuse throughout your site."

Let's explore some useful mixins, all of which I use regularly on projects I'm involved in.

Individualized Break Points

@mixin break($point) {
    @if $point == grande {
        @media (min-width: 30em) { @content; }
    }
    @else if $point == venti {
        @media (min-width: 50em) { @content; }
    }
    @else if $point == tetra {
        @media (min-width: 70em) { @content; }
    }
    @else if $point == supersize {
        @media (min-width: 90em) { @content; }
    }
}

Along with flexible grids and scalable images, media queries are one of the three pillars of responsive web design. So they are pretty important! Initially,@mediawas used in<head>to call in entirely new stylesheets at certain viewport widths or resolutions. For performance reasons, we then migrated those all into the same stylesheet, down at the bottom. But having to scroll to different areas within the stylesheet is still not ideal especially during initial development or while squashing bugs. It is much more logical to deal with all the elements together. Sass swoops in and saves the day here. For example…

body {
    font-size: 16px;
        @include break(grande) {
            font-size: 1.1em;
        }
        @include break(venti) {
            font-size: 1.3em;
        }
}

How you name your media queries is entirely up to you, and it can be fun coming up with original ones. In this example, I am using Starbucks cup sizes, but your naming conventions are totally up to you. CSS Tricks has a fun discussion on this very topic.

Clearfix

The clearfix hack is one that is so universally used in the dev world that it is difficult to come across a site that doesn't use it. Nicolas Gallagher's implementation is probably the best and most well-known hack, so we're going to retrofit it for Sass.

@mixin clearfix {
    zoom: 1;
      &:after,
      &:before {
          display: block; 
          height: 0; 
          overflow: hidden; 
          content: "\0020"; 
      }
      &:after {
          clear: both;
      }
}

Any element you wish to force-clear, now, just needs an @include clearfix; in it. Easy.

Consistent Link Styles

It's rare nowadays that you will use a different style for a:hover and a:active. This mixin covers the three main a:states.

@mixin linkstyles($property, $value) {
    &:hover, 
    &:active, 
    &:focus {
        #{$property}: $value;
    }
}

Compass and Bourbon are two excellent mixin libraries for Sass that you can include with your projects (instead of writing your mixins yourself).

Extensions

The @extend function lets you share a set of CSS properties from one selector to another. There really is no need to keep repeating similar styles. In fact, it forces you to take a block-based approach (SMACSS, OOCSS, Atomic Design, etc.) towards your CSS and design.

.dialogue-box {
    width: 40em;
    height: 20em;
    color: rgba(0,0,0,.5);
}
.error {
    @extend .dialogue-box;
    background: red;
}
.success {
    @extend .dialogue-box;
    background: green;
}

becomes…

.dialogue-box,
.error, 
.success {
    width: 40em;
    height: 20em;
    color: rgba(0,0,0,.5);
}
.error {
    background: red;
}
.success {
    background: green;
}

In Conclusion

Designers and developers are now tackling roles from a unified point of view, as opposed to the job-specific ones of the past. And as new technologies and methodologies emerge, we are forced to reevaluate our workflows from both viewpoints. Sass is one of these changes that is affecting both ends of spectrum and I can't imagine moving away from it anytime soon. Today, I wouldn't advise designing for the web without a preprocessor.

How about you? What has your experience with Sass been? Do you prefer LESS or another preprocessor? Let us know in the comments below, or on Facebook or Twitter.

Jan 16, 2014
The Sass Way (And Other Thoughts on Development)

Get Email Updates (It's FREE)

Zero Spam. Unsubscribe Anytime.

Made With In Whistler