12 Sep 2012

Yesterday, I attended a training on Sass and Compass by Roy Tomeij organised by Fronteers. Sass is a CSS meta language and compiles to CSS, to make it easier to maintain than CSS yet still usable in the same browsers.

Compass is a plugin for Sass and offers a lot of often used patterns, but it does more, which I'll explain below.

Sass is a front-end meta language (or CSS preprocessor) that compiles to CSS. It has 2 syntaxes, "Original Sass" and SCSS. SCSS is easiest to start with if you already know CSS, because it just adds syntax. "Original Sass" and other CSS meta languages like LESS are out of scope here. How to run Sass is also out of scope, but let me just say that there is a free utility called Scout that makes it easier. However, compiling on the command line is a lot faster. For debugging in the browser you can try FireSass or enable line numbers when compiling Sass.

As mentioned, it's better if you already know CSS. As anyone who ever used Frontpage knows, preprocessors can result in bloated code. That's why it's recommended to monitor the generated CSS, especially in the beginning. You'll need to learn how the Sass compiler works and that way you can make really clean code.

Although the CSS3 spec is very much alive and new features that make the lives of developers easier are added regularly, it takes time for all browsers, particularly those that don't push new versions coughIEcough, to support these. For some of these features, Sass (e.g. in combination with the Compass CSS3 module) is a good workaround, because it results in code that works on current browsers and it is easy to incorporate fallbacks.

So far I've only argued why Sass is a good idea, now I want to show that it's really easy to use and how you can profit from it as a developer. I won't go into all topics discussed in the training, but I'll add a list of links of the basic concepts in the Sass documentation.

Sass supports:

An annotated example:

// This is a valid Sass comment. It will not be visible in 
// the compiled CSS
/* This comment will be visible in the CSS */

// This is a variable with name maincolor and value 
// <span style="color: #f00;">#f00</span> of the data-type color.
$maincolor: #f00;
// A variable with the data-type number
$val: 1;
// Also a variable with the data-type number
$example-size: 10px;

.maincontent {
  // Using a variable
  color: $maincolor;
  // Addition operator
  width: 500px + 10px;
  // Mixing unit types is possible, if compatible (no using % here!)
  height: 5in + 10pt;
  // Division operator
  margin-left: $example-size / 3;
  // Round function
  margin-right: round($example-size / 3);
  // Using / when needed in CSS, by interpolation
  border-radius: #{$example-size} / 3px;

  // Nesting. This applies to an h1 in the .maincontent
  // Although nesting is very convenient for maintaince try
  // to prevent nesting more than 4 levels deep, because
  // otherwise it results in very long selector statements
  // in the CSS. This is bad for performance.
  h1 {
    border: 1px solid black;
  }
}

// Declaring a function to modify width
// A function returns just a value
@function new-width($width) {
  $border-width: 1;
  @return 10 + (2 * $border-width);
}

// Interpolation of the variable $val
.sidebar-#{$val} {
  // Using the function
  width: new-width(100);
}

// Declaring a mixin to generate column rules
// A mixin returns a block of code.
@mixin add-columns($amount) {
  @for $i from 1 through $amount {
    .column-#{$i} {
      $bgcolor: red;
      @if $i &lt; 2 {
        $bgcolor: blue;
      }
      border: $bgcolor;
    }
  }
}

.column-wrapper {
  // Using the mixin
  @include add-columns(2);
}

This compiles to:

/* This comment will be visible in the CSS */
.maincontent {
  color: red;
  width: 510px;
  height: 5.139in;
  margin-left: 3.333px;
  margin-right: 3px;
  border-radius: 10px / 3px;
}
.maincontent h1 {
  border: 1px solid black;
}

.sidebar-1 {
  width: 12;
}

.column-wrapper .column-1 {
  border: blue;
}
.column-wrapper .column-2 {
  border: red;
}

Compass is a library for Sass, and a bit more. It adds:

  • Generating sprites (including magic sprites, where a directory of PNG images is automatically converted to a sprite and the required CSS with positions!)
  • A slew of mixins that automatically adds vendor-prefixes for features that require them, e.g. border-radius.
  • Much used features, such as a reset style or a mixin for clearfix.

Because Sass is a compiler, it will check the input for syntax errors. The compiler can even be configured to do minification. This will concatenate the included files (which is better for performance, because there is only 1 HTTP request), compress the result and also remove all comments, except those starting with /*! which is conform other minifiers.

It is advised to group all variables for e.g. colors in one file and all mixins in files separated from the other code. It is easy to make a modular set-up in Sass, because you can include other Sass files that are automatically combined to one file. Because the architecture of a web project is beyond the scope of this post, I want to refer to the book that Roy is writing on this subject. He also has a presentation about modular and reusable front-end code. Another way to learn more about CSS architecture is to be guided by Smacss.