Getting started with Sass and Compass

So your friend, co-worker, web-buddy or whomever told you about Sass, Compass … or both. Great! Now what? In this beginner guide we take you through the first steps of getting started with Sass and Compass. We walk you through installation, creating a test project, compiling your first lines of Sass to CSS, and we even “mixin” a little Sass history.

Install Sass and Compass

Sass and Compass get installed as Ruby gems so you’ll need to have Ruby on your machine.

If you’re on Windows, you can run the Ruby Installer. On Linux, Rails Ready provides several Ruby essentials. On OS X, Ruby is already installed by default so Ruby just works.

Getting Ruby in place is beyond the scope of this article, so, if you hit any snags hit up the mailing list if you need help finding the right resources for getting Ruby on your machine.

Install Sass

Ok, let’s install Sass! Open up your Terminal.app and type:

Windows:

gem install compass

Linux / OS X:

sudo gem install compass

For Linux and OS X folks, depending on your setup, you may or may not need to install gems under the sudo user. For example, if you are using RVM, you won’t need to install your gems under the sudo user.

Ok, I know what you’re thinking. I just said that we are going to install Sass, but I just told you to install Compass based on that directive. The truth is, Compass requires Sass and when you run that command you should see something like this:

$ sudo gem install compass
Fetching: sass-3.1.3.gem (100%)
Fetching: compass-0.11.3.gem (100%)
Successfully installed sass-3.1.3
Successfully installed chunky_png-1.2.0
Successfully installed fssm-0.2.7
Successfully installed compass-0.11.3
4 gems installed

If that’s not what you saw when you ran that command, you may not have Ruby or Ruby Gems on your machine. Covering this in detail is a bit beyond where I want to go in this post, so seek help at the mailing list if you encounter any issues.

If you are intimidated by the command line, don’t be. John Long has written an awesome guide titled, “The Designer’s Guide to the OSX Command Prompt”, that should get you up to speed on the subject.

Also, there are 2 GUI apps for Sass/Compass, but we’ll be assuming command-line usage for this guide.

CSS Parser

I also like to install css_parser to take advantage of all the features of compass stats which outputs statistics of my Sass stylesheets. It outputs a report that gives a count of the Sass rules, properties, mixins defined and mixins used as well as the CSS rules and properties that get output from your Sass-stylesheets.

Run this command to install css_parser

gem install css_parser

Now you are ready for some hardcore Sass and Compass action!

Create a test project

The easiest way to get started with something new is to just jump right in. On that note. Head to the place you store you codes (or where ever you’d like to store this test project) and run this command.

compass create sass-test

Alternatively you can pull down the test project from GitHub using this:

git clone https://github.com/thesassway/sass-test.git

But that would completely defeat the purpose of learning how to do this on your own.

Moving on. Change directory (cd) into the newly created /sass-test directory and open it up in your favorite editor. I use TextMate, but I’ve been contemplating trying out Vim or Sublime Text 2. We’ve covered Vim quite a bit on The Changelog, so take a peek at the search results for Vim on The Changelog and dig in.

Compile Sass to CSS

This is the easiest part. Sass and Compass does all the hard work, so run this command and let Compass do its thing.

compass watch

You should see something like this if you’ve done well with following along.

$ sass-test git:(master) compass watch
FSSM -> An optimized backend is available for this platform!
FSSM ->     gem install rb-fsevent
>>> Compass is polling for changes. Press Ctrl-C to Stop.

If that’s the case go ahead and let out a loud “yee” and pat yourself on the back because you are now ready to start writing your CSS … The Sass Way!

The compass watch command does exactly what you would think it would do – it watches your Sass files for changes (saved changes) and automatically compiles your Sass to CSS. How does it know where the Sass is and where the CSS should be compiled to? That’s a great question, and one that I’ll cover in more detail in a future post titled “Configuring Compass”.

In the meantime, take a look at config.rb located in the root of our sass-test project. TheCompass configuration is essentially the brain of Compass and defines a number of variables letting Compass know where your Sass, CSS, images and JavaScript files are located, what extensions to require, what syntax you prefer, the output style and much more.

Write some Sass

Ok, before we actually write some Sass, it’s important to know that Sass has some history to it. In fact, one of the hardest things to grasp is that Sass actually has two syntaxes – and that’s often what either confuses or intimidates people and deters them from even giving it a try. How do I know? Because that’s exactly how I felt BEFORE I bit the bullet and took the proverbial plunge. But let’s not get off track here.

Sass is like CSS. Ok, that’s misleading. Sass CAN BE like CSS. I mentioned that Sass has some history to it and actually has not one, but two syntaxes. One of the syntaxes is even named “Sass” which adds even more confusion to the mix. The main syntax is referred to as “SCSS” (for “Sassy CSS”) and is new as of Sass 3. The older syntax (part of that history I mentioned) is referred to as the indented syntax (or just “Sass”).

Now that we’ve covered a bit of the history of Sass and the fact that it has two syntaxes, I believe we are ready to write some code. Or should I say SCSS – because the SCSS syntax is like CSS and was designed to be a superset of CSS3’s syntax. This means that every valid CSS3 stylesheet is valid SCSS. In fact, you can copy the contents of a CSS file and paste it into a SCSS file and Sass will compile it to clean CSS.

Let’s test out this “theory” and copy the contents of our css file from this blog and paste it intoscreen.scss in our test project and run compass compile. Take a look at screen.css now and you’ll see that Sass and Compass have compiled that compressed un-readable CSS to readable, perfectly indented CSS along with comments of where the code came from for debugging purposes.

Conclusion and next steps

This example is obviously not the most practical example, and technically we didn’t write anycode. I just wanted to prove to you that there can be next to zero effort in transitioning to Sass because you just did it.

The next step is to take advantage of the features of Sass and Compass that are now available to you, when you choose to use them. That’s the best part of this transition. You can incrementally step into what Sass and Compass have to offer. There’s no reason to be intimidated or feel it will “take weeks” to do.

A standard module definition for Sass

Since becoming a fan of Sass, one thing that has bothered me is that not much has been written about best practices for structuring Sass projects. This is one of a series of articles we will be writing to talk about some of the things that folks are doing to make their projects better.

In this article, I’d like to kickstart the discussion on developing a Standard Module Definition for Sass. I’ll start by sharing a couple of principles that I’ve found helpful for structuring Sass projects. (The principles here apply mostly to writing Sass for non-library code. We’ll talk more about some ideas for structuring library modules in a future article.)

1. A module is a unit of code contained in a partial

I like to define modules in Sass partials. Since Sass doesn’t currently have a way to namespace code, the easiest way to group code by function is to do so in a partial. One module per file. Example module names in typical projects might include: buttons, forms, lists, and typography.

2. Importing a module should never output code

I’m a strong believer in keeping your modules free of anything that would cause immediate CSS output. The idea is that you should be able to import any number of modules into your code-base and then make selective calls to control the output. This pretty much limits modules to mixins, functions, and variable definitions. (Sass 3.2 also introduces placeholder selectors which could also be used in a module definition.)

3. Each module should have a primary mixin

If appropriate, a primary mixin should be included in each module that outputs the standard usage of the module. This one is a little tricker to explain with words, so let me show you in code.

Here is an example _buttons.scss:

// Primary mixin
@mixin buttons {
  a.button, button {
    @include button(black, silver);
    &.blue  { @include button(white, blue); }
    &.red   { @include button(white, red); }
    &.green { @include button(white, green); }
  }
}

// Button mixin
@mixin button($text-color, $bg-color) {
  font: 12px bold sans-serif;
  padding: 3px 8px;
  @include color-button($text-color, $bg-color));
  &:hover, &:focus { @include color-button($text-color, lighten($bg-color, 10%)); }
  &:active { background: darken($bg-color, 5%); }
}

// Color button mixin
@mixin color-button($text-color, $bg-color) {
  color: $text-color;
  border: 1px solid mix(black, $bg-color);
  @include background-image(
    linear-gradient(
      lighten($bg-color, 5%),
      darken($bg-color, 5%)
    )
  );
}

...

The idea here is that the buttons module includes all kinds of mixins for creating and styling buttons, but the primary mixin demonstrates and applies the default usage of the appropriate mixins. This makes it super simple to use the default behavior for a module in a stylesheet.

Here’s an example of how I often combine modules in my main stylesheet:

.content {
  @include typography;
  @include buttons;
  @include lists;
  @include forms;
  ...
}

4. The name of the primary mixin should inherit the name of the module

I’d recommend that you try to pluralize your module names, where appropriate, and the name of your main mixin for that module should be the same as the name of the module itself. This simple naming convention will make it easy to import and use your modules without thinking hard about the names.

5. Variable definitions should always be defaulted

If a module defines top-level variables, they should always be defined with the !defaultdirective. This will make it much easier to override those variables in a theme stylesheet or when reusing the module for other purposes.

Here’s an example of using the !default directive to declare defaults for variables within a module:

$base-font-family: Helvetica, Arial, sans-serif !default;
$fixed-font-family: monospace !default;

6. Almost all project CSS should be written in modules

I like to code almost all of my CSS in modules using this pattern. This makes it much easier to reuse styles across stylesheets for a given project or even to share code between projects. It also helps me think about my code in a modular way from the very beginning – a discipline that I find quite helpful.

For me, modules have become the basic units or building blocks of my Sass projects. What practices do you find helpful for structuring your own projects?

Building a CSS framework with Sass

Over the past few years, the “CSS framework” topic has been one of the most hottest topics. There have been a number of permutations of CSS grid frameworks; fixed, fluid, elastic, responsive … you name it. To most seasoned front-end veterans, the topic of CSS frameworks isn’t new. But, let’s face it. Building a foundation of styles for each new project can be tedious and repetitive. But not with Sass.

Why do we use CSS Grid Frameworks?

Frameworks like Blueprint960 Grid SystemGrid Coordinates and Susy have created ways for designers to skip the repetitive, mundane and most importantly the math. With a CSS framework, front-end devs and designers can get a site laid out relatively quick with a minimal number of bugs, on top of a heavily tested code base.

Treesaver Boilerplate

At my day job I work with a company called Treesaver where we build magazine-style websites in HTML5 with an amazing bit of, “self-titled”, JavaScript called Treesaver. When I started with Treesaver a little over a year ago, that amazing bit of JavaScript and the ever transforming HTML5 spec was just about all we had to work with. All our HTML5 templates, JavaScript and CSS stylesheets were custom built from the ground up. In order to rapidly create the magazine-style websites we needed to develop, I immediately knew we needed to develop a custom CSS framework robust and flexible enough to support a wide array of grid layouts.

Sass, the perfect fit for creating CSS frameworks

I was introduced to Sass by my boss. Having access to variables, mixins, nested selectors and selector inheritance was quite literally impossible with vanilla CSS. Needless to say, I picked up Sass with a grin from ear to ear and just ran with it. The result? Seasons, a boilerplate for our self-titled JavaScript library Treesaver.

I immediately got into the variables and operations to calculate the grid. At the time I was tasked with designing and building about 5 publications, with slightly different grid measurements. I developed the core logic to determine all the math instead of pulling out the calculator for every calculation. Once I was done, all I had to do was swap out a class for the skin and voila. Magic! Everything updated to the new skin and grid layout.

Every new project brought new challenges

Of coarse our challenges didn’t stop there. Each new project added new challenges to the table. The core code was refined to a series of simple loops, image sizing was added and positioning was greatly improved. When adding a vertical grid, even the semantics of $column was brought into question and changed to $module-w based on Mark Boulton’s article, rethinking grids. The Sass looked nice and clean but the CSS output was starting to get hefty. Bloated CSS is a know problem with frameworks. They tend to just keep growing to satisfy every need, and making things more generalized and lean was a great ordeal. So I turned to Sass’s boolean features enable entire portions of the framework to be able to turn on and off. Sexy!

Before diving too deep into the code, Treesaver creates a number of unique challenges. All the HTML for layout exists in one file, resources.html. All the content is stripped from the <article>tags of pages. and placed into these “grids”. This manipulation of the DOM by the Treesaver JavaScript can be tough to figure our where some objects are placed. If that isn’t enough, the layouts are algorithmically chosen based on the amount and kind of content that can fit on each page. With all this complexity, the reasons for releasing a boilerplate were adding up.

All projects should start on a grid, but with grid layouts being defined in a separate file from the content grids need to be generated so the designer can do the taboo, layout in the HTML. That said, its just a matter of simple configurable loops to generate the output needed. These loops calculate for classes that position elements across the grid, So if I wanted an element to start on column 3 with a width of 4 columns it would be named <div class="c3 w4">. Maybe you want to turn the vertical grid on and position it 2 rows down? Add the class r2. It all sounds good so far but what if a project needs no less than a 30 column grid for some reason? Or a column width of 3px? These values may sound absurd but this framework is written in Sass so we have no excuse for locking down any values.

// GRID MEASURMENTS
@for $i from 1 through $columns // loop defines columns. c1, c2, c3 . . .
  .c#{$i}
    margin-left: grid($i) - $module-w
@for $i from 1 through $columns // loop defines widths. w1, w2, w3 . . .
  .w#{$i}
    width: grid($i)

// Vertical grid
$vertical-grid: false !default
$rows: 10 !default
@if $vertical-grid // Generate only if $vertical-grid is true. This code is usually not nessisary.
  @for $i from 1 through $rows // loop defines rows. r1, r2, r3 . . .
    .r#{$i}
      position: absolute
      top: (grid($i, $module-h) - $module-h) + $top
  @for $i from 1 through $rows // loop defines heights. h1, h2, h3 . . .
    .h#{$i}
      height: grid($i, $module-h)

Image resizing has been the trickiest part in creating Seasons. In order for Treesaver to calculate the layouts it needs to know the dimensions of each element, and while the dimensions of different sized images can be defined in the content, complex layouts would require about twelve different images to be defined in the content, something that was just getting too hard to manage. Now Sass is great at looping through and calculating ways to resize these images but can result in bloat just as easily. In fact, the earlier code was taking about 50k just to resize images! Pulling on nested mixins in the configuration containing the ratios used throughout the publication. Using a custom selector for ratio instead of a class targeting measurements for various page along with image ratios became smaller while supporting more use-cases.

@mixin ratios
  +ratio(16, 9)
  +ratio(4, 3)

// IMAGE + PAGE RATIOS
=ratio($width, $height, $cols: $columns)
  @for $i from 1 through $cols
    .r#{$width}x#{$height}.w#{$i},.container.w#{$i} [ratio="#{$width}x#{$height}"] img // Grid ratio, figure ratio.
      width: grid($i) // Width spans all columns
      height: round(grid($i) * ( $height / $width )) // Height is the proportion of the width.

+ratios // Run the code above. Ratios are defined in _config.sass

Creating powerful layout tools that don’t add heft to your file is another great point of creating a Sass framework. Creating tools for people to simply use the grid and control typography are just as if not more important for frameworks than just caring about the generated grids. Users should have as much control over aspects of layout from the stylesheets as they do with the classes the framework generated. For example grid is added as a function that generates different values based on the grid to use in stylesheets. Debug tools are another add-on that highlight elements. Ever made an element bright red just to see if it was showing up on the page at all? Well one-letter mixins rgbcm, and y will highlight elements in a verity of colors so you can quickly debug layouts. Also, throwing in some modular-scales, sprites, and CSS3 mixins for some fantastic layout possibilities. Want a list? you can find it here

Now configuring this monster may seem like a tall order, but it’s not that bad. Using the !defaultnot everything needs to be defined. In fact, out of the box Seasons is set up so it works, no need to change anything unless you want a value changed. The nature of frameworks is to be bloated, but the config allows you to trim out a number of features you may not wish to use. Not using fullbleed figures or inset captions, or want to write your own variation? Just turn them off in the config. Building styling frameworks in Sass is a whole new ballgame. The level of customization and flexibility needs to be far greater than that of CSS frameworks because this is how style frameworks should always work.

Responsive Web Design in Sass: Using media queries in Sass 3.2

In Responsive Web Design in Sass Part 2 I wrote about using media queries in Sass 3.1. At the time, I was mostly limited to the (still very cool) @media bubbling feature. I also pointed out some of the shortcomings.

At the end of the post I previewed how you can use @content blocks, one of the emerging features of Sass 3.2, to write a mixin that can really help to simplify using media queries in Sass. With Sass 3.2 nearly upon us, I am happy to report that media queries have become the first-class citizens they deserve to be. Let’s see what’s new.

Variables in queries

If you tried to use a variable in the media query test in Sass 3.1 it would fail by simply spitting out the actual text of the variable name. This is fixed in Sass 3.2, and works pretty much as I always expected it would.

$break-small: 320px;
$break-large: 1200px;

.profile-pic {
  float: left;
  width: 250px;
  @media screen and (max-width: $break-small) {
    width: 100px;
    float: none;
  }
  @media screen and (min-width: $break-large) {
    float: right;
  }
}

Compiles to:

profile-pic {
  float: left;
  width: 250px;
}
@media screen and (max-width: 320px) {
  .profile-pic {
    width: 100px;
    float: none;
  }
}
@media screen and (min-width: 1200px) {
  .profile-pic {
    float: right;
  }
}

Variables as full query

You’re not limited to using variables in the numerical part of a @media test. Go ahead and set the whole test as a variable. (Note the need for the interpolation braces #{})

$information-phone: "only screen and (max-width : 320px)";

@media #{$information-phone} {
  background: red;
}

Compiles to:

@media only screen and (max-width : 320px) {
  background: red;
}

Variables on either side of the colon in a query

You can also get really abstract and set a variable for items on either side of the colon in a test. I can see this being very usefull in building flexible responsive frameworks.

$width-name: max-device-width;
$target-width: 320px;

@media screen and ($width-name : $target-width) {
  background: red;
}

Compiles to

@media screen and (max-device-width: 320px) {
  background: red;
}

You can also do math on a variable in a query, like so:

@media screen and ($width-name : $target-width + 1) {
  background: red;
}

Compiles to

@media screen and (max-device-width: 321px) {
  background: red;
}

Variables in queries, using @content

In Responsive Web Design in Sass Part 2, I illustrated how to write some nicely abstracted media query systems using @content blocks in mixins. Now you can take that a step further by using variables in the actual queries. I think this will be very helpful in refining a set of breakpoints.

On my next project, I think I’ll start with some of the usual device-related breakpoints (320, 480, 720) as “placeholder” breakpoints. Then as I progress in building my design I’ll alter those to whatever values suit my design.

SCSS

$break-small: 320px;
$break-large: 1024px;

@mixin respond-to($media) {
  @if $media == handhelds {
    @media only screen and (max-width: $break-small) { @content; }
  }
  @else if $media == medium-screens {
    @media only screen and (min-width: $break-small + 1) and (max-width: $break-large - 1) { @content; }
  }
  @else if $media == wide-screens {
    @media only screen and (min-width: $break-large) { @content; }
  }
}

.profile-pic {
  float: left;
  width: 250px;
  @include respond-to(handhelds) { width: 100% ;}
  @include respond-to(medium-screens) { width: 125px; }
  @include respond-to(wide-screens) { float: none; }
}

CSS

.profile-pic {
  float: left;
  width: 250px;
}
@media only screen and (max-width: 320px) {
  .profile-pic {
    width: 100%;
  }
}
@media only screen and (min-width: 321px) and (max-width: 1023px) {
  .profile-pic {
    width: 125px;
  }
}
@media only screen and (min-width: 1024px) {
  .profile-pic {
    float: none;
  }
}

Nothing is Perfect

@extend within @media

There are features and optimisations I’d like to see regarding @media handling in Sass. For example @extend doesn’t behave like I’d expect when I use it in a media query.

When I write the Following in SCSS:

.red {
  color: red;
  }

.blue {
  color: blue;
}

@media only screen and (max-width : 300px){
  .blue {
    @extend .red;
    margin: 10px;
  }
}

I intended for the generated css to look something like:

.red {
  color: red;
}
@media only screen and (max-width: 300px) {
  .blue {
    color: red;
  }
}

.blue {
  color: blue;
}

@media only screen and (max-width: 300px) {
  .blue {
    margin: 10px;
  }
}

But what I really got wasn’t nearly as useful.

.red, .blue {
  color: red;
}

.blue {
  color: blue;
}

@media only screen and (max-width: 300px) {
  .blue {
    margin: 10px;
  }
}

This is a hairy issue, and different use cases suggest different results. Eventually this may just bedisallowed.

Combining @media Queries on Compile

One feature I hear a lot of people bring up with @media bubbling is that you often end up with the same query in many places in your compiled CSS. The resulting CSS would be much smaller and more closely resemble “handcrafted” CSS if all the rules that match a particular query be combined when the CSS is compiled.

.profile-pic {
  @media screen and (max-width: 320px) {
    width: 100px;
    float: none;
  }
}

.biography {
  @media screen and (max-width: 320px) {
    font-size: 1.5em;
  }
}

It would be nice (and smaller) if that became:

@media screen and (max-width: 320px) {
  .profile-pic {
    width: 100px;
    float: none;
  }
  .biography {
    font-size: 1.5em;
  }
}

But instead we get:

@media screen and (max-width: 320px) {
  .profile-pic {
    width: 100px;
    float: none;
  }
}

@media screen and (max-width: 320px) {
  .biography {
    font-size: 1.5em;
  }
}

Nothing’s broken here, but it’s certainly not optimal. I think this would be a great issue to tackle, and it looks like there are some other smart optimisations they’re considering.

So go get it!

As before, you don’t have to work hard to get the new good stuff. Just run the following in your command line and you’re all set.

gem install sass --pre

How to structure a Sass project

One of the most useful features of Sass is being able to separate your stylesheets into separate files. You can then use the @import directive to include the source of your individual files into one master stylesheet.

But how should you structure your Sass projects? Is there a standard way of separating out your CSS files?

Basic directory structure

I like to layout my Sass projects like this:

stylesheets/
|
|-- modules/              # Common modules
|   |-- _all.scss         # Include to get all modules
|   |-- _utility.scss     # Module name
|   |-- _colors.scss      # Etc...
|   ...
|
|-- partials/             # Partials
|   |-- _base.sass        # imports for all mixins + global project variables
|   |-- _buttons.scss     # buttons
|   |-- _figures.scss     # figures
|   |-- _grids.scss       # grids
|   |-- _typography.scss  # typography
|   |-- _reset.scss       # reset
|   ...
|
|-- vendor/               # CSS or Sass from other projects
|   |-- _colorpicker.scss
|   |-- _jquery.ui.core.scss
|   ...
|
`-- main.scss            # primary Sass file

Primary stylesheet

This allows me to keep my primary Sass file extremely clean:

// Modules and Variables
@import "partials/base";

// Partials
@import "partials/reset";
@import "partials/typography";
@import "partials/buttons";
@import "partials/figures";
@import "partials/grids";
// ...

// Third-party
@import "vendor/colorpicker";
@import "vendor/jquery.ui.core";

Modules, partials, and vendor

As you can see this divides my project into three basic types of files. Modules, partials, and vendored stylesheets.

  • The modules directory is reserved for Sass code that doesn’t cause Sass to actually output CSS. Things like mixin declarations, functions, and variables.
  • The partials directory is where the meat of my CSS is constructed. A lot of folks like to break their stylesheets into header, content, sidebar, and footer components (and a few others). As I’m more of a SMACSS guy myself, I like to break things down into much finer categories (typography, buttons, textboxes, selectboxes, etc…).
  • The vendor directory is for third-party CSS. This is handy when using prepackaged components developed by other people (or for your own components that are maintained in another project). jQuery UI and a color picker are examples of CSS that you might want to place in the vendor directory. As a general rule I make it a point not to modify files in my vendor directory. If I need to make modifications I add those after the vendored files are included in my primary stylesheet. This should make it easy for me to update my third-party stylesheets to more current versions in the future.

Using a base partial

In my partials directory you will also notice that I have a base partial. The purpose of this partial is to load up my Sass environment so that it’s easy to construct a stylesheet.

It might look something like this:

// Use Compass ('cause it rocks!)
@import "compass";

// Font weights
$light: 100;
$regular: 400;
$bold: 600;

// Base Font
$base-font-family: sans-serif;
$base-font-weight: $regular;
$base-font-size: 13px;
$base-line-height: 1.4;

// Fixed Font
$fixed-font-family: monospace;
$fixed-font-size: 85%;
$fixed-line-height: $base-line-height;

// Headings
$header-font-weight: $bold;

@import "modules/all";

The base stylesheet sets a couple of global variables and loads up all of my Sass modules. Again modules are not allowed to contain anything that would cause CSS output when importing. Tying all of my varibles and modules up into a base partial gives me access to my entire Sass environment whenever I’m setting up a new stylesheet with a single import statement. This allows me to build multiple stylesheets by importing different partials. Multiple stylesheets are handy once a project grows to a certain size.

One step further

At UserVoice we take this pattern one step further. Since we have multiple sub-projects all bundled together in a single Rails app, we bundle each sub-project into a separate top-level directory. Our stylesheet directory looks more like this:

stylesheets/
|
|-- admin/           # Admin sub-project
|   |-- modules/
|   |-- partials/
|   `-- _base.scss
|
|-- account/         # Account sub-project
|   |-- modules/
|   |-- partials/
|   `-- _base.scss
|
|-- site/            # Site sub-project
|   |-- modules/
|   |-- partials/
|   `-- _base.scss
|
|-- vendor/          # CSS or Sass from other projects
|   |-- _colorpicker-1.1.scss
|   |-- _jquery.ui.core-1.9.1.scss
|   ...
|
|-- admin.scss       # Primary stylesheets for each project
|-- account.scss
`-- site.scss

As you can see each sub-project has it’s own primary stylesheet, modules, partials, and base. Vendored stylesheets are typically versioned and have their own top-level directory. This is a handy pattern to use on very large Sass projects.

Further exploration

Now that I’ve laid out my own method for this, you may want to explore how other people have structured their Sass projects. There’s actually a lot of variation in what you can do here. And some methods may work better on different projects:

Sass vs SCSS: which syntax is better?

Since the creation of Sass nearly 5 years ago, it has been plagued by many levels of controversy. It billed itself as “a better CSS” and added brand new features unheard of to CSS authors such as variables, nesting and mixins. Sass also introduced an entirely different indentation-oriented syntax and a brand new perspective on how to author CSS.

The Sass syntax

The indented syntax of Sass was inherited from its first-born brother Haml. And while Sass and Haml once got along – Hey, they even shared the same Ruby Gem! – dissension in the family caused the two languages to split and go their separate ways. Each seeking its own fame and fortune in the land of Open Source opportunity.

One common objection among Sass detractors is that the indented syntax is so foreign to CSS. Why spend the time learning a language that is radically different from CSS? This difference, they fear, will make it hard for them to continue to remain fluent in a language with as many nuancesand subtleties as CSS. What if Sass is just a fad? What if it doesn’t last? What if it doesn’t gain traction among the masses? What if all their code and newly formed best practices fall by the wayside should the “downfalls” of Sass become a reality? What if … ah, you get the point.

And the objections trail on …

SCSS to the rescue!

In version 3 of Sass, the SCSS (Sassy CSS) syntax was introduced as “the new main syntax” for Sass and builds on the existing syntax of CSS. It uses brackets and semi-colons just like CSS. It doesn’t care about indentation levels or white-space. In fact, Sass’s SCSS syntax is a superset of CSS – which means SCSS contains all the features of CSS, but has been expanded to include the features of Sass as well. In layman’s terms, any valid CSS is valid SCSS. And in the end, SCSS has the exact same features as the Sass syntax, minus the opinionated syntax.

Those who are new to Sass have less to learn. And as for Sass detractors, well, they can no longer complain about the syntax. As far as I’m concerned, SCSS is the new CSS.

Which syntax is better?

If you are an old hat at Sass, chances are you’ve got an opinion about which syntax is better. And there are a lot of good people on both sides of the aisle. Some prefer Sass, the original syntax – while others prefer SCSS. Either way, there’s no need for panic or worry because Sass’s indented syntax has not been and will never be deprecated!

I’m not even going to pretend to be unbiased in this debate. I myself am a huge fan of SCSS. A recent convert, actually. I was once a die-hard fan of the indented syntax, but I’ve changed my mind on the matter and I wrote this article to share why.

Before I get to that, let me explain the reasons I loved Sass, and why I almost didn’t give SCSS a chance.

Pros for Sass

Reason #1: The Sass syntax is more concise

It’s true. The indented syntax removes the need for semi-colons and braces. It doesn’t require that you use the verbose @include to mixin your mixins. Instead it uses the + operator which requires less typing and makes your code simpler, and easier to read.

Reason #2: The Sass syntax is easier to read

Because of its rules about indentation, it’s kind of hard to write unreadable Sass. Sass forces you to write your code the same way every time. There’s no option for venturing off and making your own style of commenting and formatting. It’s very strict on how things can be done. On large teams or in situations where you aren’t the sole author of all the code, this could be a huge plus. It forces the team into more strict coding practices (much like what XHTML did for HTML) and leaves little room for deviation from the beaten path.

Reason #3: The Sass syntax doesn’t complain about missing semi-colons

Ok, I know this probably belongs with reason #1, but I’m listing it separately because it was one of the major reasons I loved the original syntax. Not only did I not have to type semi-colons at the end of every attribute/value pair, but Sass ensured that my output always had the correct semi-colon placement. This is a huge win over writing vanilla CSS which doesn’t complain about semi-colons (but, the CSS validator does). When I wrote straight CSS I was always surprised by how many times a misplaced semi-colon was the reason a rule didn’t get applied properly.

This isn’t a points war

Now, before I get too far ahead of myself, I just want to say that this article isn’t a 3 points for Sass, 8 points for SCSS argument. Sure, I list more points for SCSS, but your feelings on each of the points are going to vary. For some, the three points I’ve stated above as pros for Sass will be persuasive enough to keep you using it. For many, switching back to something more like CSS after using Sass will seem like lunacy. For me that’s exactly what it felt like the first time I tried to do a project in SCSS. The brackets and semi-colons were back. A lot of what I hated about CSS was back. It was like taking a step backwards instead of continuing to push forward (that’s the point right?). In fact, like any good citizen of the Internet, I tweeted my hatred of SCSS. I had dipped my toes in the water and found it too chilly for my taste. So I hung up my curly-braces and semi-colons and went on my way. Sass was good enough for me just as it was, thank you very much. No need to revert back to the dark ages of CSS just to get a more familiar syntax.

A change of heart?

So, what changed my heart? To tell you the truth I’m not really sure. A lot of it for sure had to do with the fact that my good friend Brandon Mathis had recently made the switch to SCSS and felt it was better. Though he offered a couple of sound arguments, which I’ve reused below, Brandon really didn’t try to persuade me too much. Mainly, he just said that he had found he liked it better. It took him a while, of course, but he was much happier now that he had made the switch.

Now Brandon has probably written more Sass than almost anyone I know. He’s on the Compass core team and has been using Sass exclusively in his projects for over 4 years now. Needless to say, his opinion holds a lot of weight with me. Also, Chris Eppstein (the author of Compass) seems to prefer the SCSS syntax. He likes it so much, that he even rewrote all of Compass in it.

I was beginning to question my resolve. So on my next project, instead of giving it a half-hearted try for a day, I decided to go all in and code the whole project in SCSS to compare the difference. The outcome? I found that it took some getting used to (as expected), but I actually began to prefer the new SCSS syntax to the original Sass syntax.

Here’s why …

Pros for SCSS

Reason #1: SCSS is more expressive

No really! I know I argued above that Sass is easier to read because of the way it forces you to write your rules and attributes with indentation, but after coding for a while in SCSS I’ve realized that I really like having the option to put a couple of attribute/value pairs on the same line. I don’t always write it this way. Normally, I write in expanded format with an attribute/value pair per line. But the compressed syntax is helpful when I only have an attribute/value pair or two. I especially like it for changing the color of a font for a hover state or adding an underline to a link.

For me SCSS ends up being more logically grouped than Sass. I can compress code that would take several lines in the Sass syntax into just a couple of lines of SCSS. Typically rules are grouped anyway. And when reading code, the number of lines of code that a bit of code uses tends to indicate its importance.

In SCSS I can compress lines that are fairly standard. And expand across several lines when I’m doing something complicated.

Reason #2: SCSS encourages proper nesting of rules

One of the huge advantages of Sass in general is that it allows you to nest selectors within selectors. This is awesome because when you change the “name” of an element, you only need to change it in one place (the outer selector) instead of in numerous places like you would when writing CSS.

But to quote Spiderman, with great power comes great responsibility.

And with the Sass syntax it really is true. It is too much power. At least for someone like me. Sass code I write tends to get too deeply nested. Why? Because it’s too easy to do. Every-time you nest something in Sass you need to be conscious of the impact that it is having on your output code.

Deeply nested Sass produces CSS with really long selectors. Especially if you use the comma operator at a high level (which is probably the most dangerous aspect of nesting). Not only is this bad because it increases the file size of the final CSS, too much specificity can become really hard to override in other rules. Importance is the result. You find yourself using !important in anger with fists in the air just to get a rule applied correctly.

Reason #3: SCSS encourages more modular code with @extend

Because nesting is harder in SCSS I find myself using @extend a lot more frequently. I tend to write code that is nested 1 – 2 levels deep underneath an abstract or virtual class name that is then extended by other selectors. Again, the curly braces, which are “ugly”, help me recognize when my code is too deeply nested and force me down the path of writing more modular code.

Oh, and if you’re not using the @extend directive, you are really missing out on the awesome-sauce of Sass! Experts agree. 🙂

Reason #4: SCSS allows me to write better inline documentation

It’s true that the Sass syntax allows a certain amount of flexibility with comments, but I find myself writing more inline-documentation directly in SCSS than Sass. A lot of this has to do with the way the code hangs together and the flexibility in syntax that SCSS provides. Braces help me group my code and comments in a way that makes more sense to me. I know we are talking aesthetics here, but more flexibility makes a difference when writing documentation.

Reason #5: Existing CSS tools often work with SCSS

I don’t actually use a lot of other tools with my CSS, but one area where this is particularly helpful is syntax highlighting. Depending on your editor preference, it may or may not have support for the indented Sass syntax. But most editors already have built-in support for CSS and tend to work well with SCSS. Also, if you do any blogging, most code highlighters support CSS, but only a handful support the Sass syntax.

Reason #6: Integration with an existing CSS codebase is much easier

I’ve often had to integrate with other CSS code when building a web site. It’s either code from some jQuery library I’m using, or a pre-existing CSS codebase. In the past I’ve often converted that code to Sass and lost valuable hours in the conversion process.

For a library, the downside is that it’s not code that you really want to maintain. When upgrading the library, the last thing you want to do is to go through the conversion process again. If it’s an existing codebase, it’s often much better to make smaller changes, than to jump into a megalithic refactoring process right away.

SCSS lets you use the existing code as is, and incrementally re-factor as you go along.

It’s true that with the indented syntax the sass-convert tool can get you most of the way there, but it’s never a completely clean conversion.

Reason #7: SCSS provides a much lower barrier to entry

From a Sass advocacy perspective, it’s much easier to convince someone to use SCSS than Sass. It’s easier to introduce them to a couple new concepts (SCSS) rather than an entirely new syntax. Designers can be very stubborn, caggy people. They are opinionated, and wary of change. They tend to do what they know well and while they do experiment with new things, experimentation with new technology is not built into the design community like it is for the programming community.

And don’t forget the other barriers to getting started with Sass. Right now you need to be familiar with the command prompt. At least enough to run a couple of commands. The command prompt is scary to the mouse-driven, button clicking designer.

Reason #8: SCSS could become the next version of CSS

Since its creation Sass and languages like it have attracted the attention of a lot of smart people. Some of those people are already thinking about adding some of the features that Sass introduced to CSS. It’s possible that the syntax introduced in SCSS could become CSS4!

Conclusion

I hope I’ve challenged you a little in your own perspective on both syntaxes. While I’m clearly arguing the advantages of the SCSS syntax, I’d also like to encourage you to go outside of your comfort zone and experiment a little more. If you’ve only been exposed to the SCSS syntax, perhaps you’d enjoy spending some time with the indented Sass syntax. And if you’re an original-flavor-only kinda person – a purist – you may benefit from giving the SCSS syntax a serious try.

As I said before, there are a lot of good people on both sides of the line in this debate. Feel free to express your own opinion in the comments below.

SASS vs LESS

“Which CSS preprocessor language should I choose?” is a hot topic lately. I’ve been asked in person several times and an online debate has been popping up every few days it seems. It’s nice that the conversation has largely turned from whether or not preprocessing is a good idea to which one language is best. Let’s do this thing.

Really short answer: Sass

Slightly longer answer: Sass is better on a whole bunch of different fronts, but if you are already happy in LESS, that’s cool, at least you are doing yourself a favor by preprocessing.

Much longer answer: Read on.

The Much Longer Answer

The Learning Curve with Ruby and Command Line and Whatever

The only learning curve is the syntax. You should use an app like CodeKitLiveReload, or Mixture to watch and compile your authored files. You need to know jack squat about Ruby or the Command Line or whatever else. Maybe you should, but you don’t have to, so it’s not a factor here. The fact that Sass is in Ruby and LESS is in JavaScript is of little consequence to most potential users.

Winner: Nobody

Helping with CSS3

With either language, you can write your own mixins to help with vendor prefixes. No winner there. But you know how you don’t go back and update the prefixes you use on all your projects? (You don’t.) You also won’t update your handcrafted mixins file. (Probably.)

In Sass, you can use Compass, and Compass will keep itself updated, and thus the prefix situation is handled for you. Bourbon is also good. There will be some back and forth on which of these project is “ahead.”

In LESS, there are also some mixin libraries battling to be the best. They are looking a lot better these days than they have in the past. Despite their marketing-y support charts, I don’t think they are quite as robust as the Sass versions. I’ve been led to understand in the past that the language of LESS itself doesn’t make it possible to build as robust of libraries on top of it. We’ll get to some of that next.

In both cases, the onus is on you to keep the preprocessor software itself up to date as well as these libraries. I also find that easier in Sass in general. For instance, Compass updates will just come automatically in CodeKit, or you use a Gem which is easy to update, while LESS mixins you’ll have to manually update a file yourself.

Winner: Narrowly Sass

Language Ability: Logic / Loops

LESS has an ability to do “guarded mixins.” These are mixins that only take affect whena certain condition is true. Perhaps you want to set a background color based on the current text color in a module. If the text color is “pretty light” you’ll probably want a dark background. If it’s “pretty dark” you’ll want a light background. So you have a single mixin broke into two parts with these guards that ensure that only one of them takes effect.

.set-bg-color (@text-color) when (lightness(@text-color) >= 50%) { 
  background: black;
}
.set-bg-color (@text-color) when (lightness(@text-color) < 50%) { 
  background: #ccc;
}

So then when you use it, you’ll get the correct background:

.box-1 {
  color: #BADA55;
  .set-bg-color(#BADA55);
}

That is overly simplified, but you likely get the idea. You can do some fancy stuff with it. LESS can also do self-referencing recursion where a mixin can call itself with an updated value creating a loop.

.loop (@index) when (@index > 0) {
  .myclass {
    z-index: @index;
  }
  // Call itself
  .loopingClass(@index - 1);
}
// Stop loop
.loopingClass (0) {}

// Outputs stuff
.loopingClass (10);

But thats where the logic/looping abilities of LESS end. Sass has actual logical and looping operators in the language. if/then/else statements, for loops, while loops, and each loops. No tricks, just proper programming. While guarded mixins are a pretty cool, natural concept, language robustness goes to Sass. This language robustness is what makes Compass possible.

For example, Compass has a mixin called background. It’s so robust, that you can pass just about whatever you want to that thing that it will output what you need. Images, gradients, and any combination of them comma-separated, and you’ll get what you need (vendor prefixes and all).

This succinct and intelligible code:

.bam {
  @include background(
    image-url("foo.png"),
    linear-gradient(top left, #333, #0c0),
    radial-gradient(#c00, #fff 100px)
  );
}

Turns into this monster (which is unfortunately what we need for it to work with as good of browser support as we can get):

.bam {
  background: url('/foo.png'), -webkit-gradient(linear, 0% 0%, 100% 100%, color-stop(0%, #333333), color-stop(100%, #00cc00)), -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 100, color-stop(0%, #cc0000), color-stop(100%, #ffffff));
  background: url('/foo.png'), -webkit-linear-gradient(top left, #333333, #00cc00), -webkit-radial-gradient(#cc0000, #ffffff 100px);
  background: url('/foo.png'), -moz-linear-gradient(top left, #333333, #00cc00), -moz-radial-gradient(#cc0000, #ffffff 100px);
  background: url('/foo.png'), -o-linear-gradient(top left, #333333, #00cc00), -o-radial-gradient(#cc0000, #ffffff 100px);
  background: url('/foo.png'), -ms-linear-gradient(top left, #333333, #00cc00), -ms-radial-gradient(#cc0000, #ffffff 100px);
  background: url('/foo.png'), linear-gradient(top left, #333333, #00cc00), radial-gradient(#cc0000, #ffffff 100px);
}

Winner: Sass

Website Niceitude

LESS has a nicer, more usable website. The Sass documentation isn’t awful. It’s complete and you can find what you need. But when competing for attention from front end people, LESS has the edge. I don’t doubt this plays a large role in LESS currently winning the popularity race.

I know that the Sass website is undergoing a major overhaul and lots of awesome people are working on it. It seems to me that it’s going very slowly though.

Winner: LESS

The @extend Concept

Say you declare a class which has a bit of styling. Then you want another class which you want to do just about the same thing, only a few additional things. In LESS you’d likely:

.module-b {
   .module-a(); /* Copies everything from .module-a down here */
   border: 1px solid red;
}

That’s an “include” essentially. A mixin, in both languages. You could use an include to do that Sass as well, but you’re better off using @extend. With @extend, the styles from .module-a aren’t just duplicated down in .mobule-b (what could be considered bloat), the selector for .module-a is altered to .module-a, .module-b in the compiled CSS (which is more efficient).

.module-a {
   /* A bunch of stuff */
}
.module-b {
   /* Some unique styling */
   @extend .module-a;
}

Compiles into

.module-a, .module-b {
  /* A bunch of stuff */
}
.module-b {
  /* Some unique styling */
}

See that? It rewrites selectors, which is way more efficient.

In LESS, every single class is also a mixin, programmatically muddies the waters, but is easier to understand at first.

As of LESS 1.4, it also supports extend. You can see some examples when we upgrade to it on CodePen. It’s a bit funky in that it doesn’t extend selectors nested in the original class unless you use an additional all keyword. Having the option to go either way seems like it’s actually more powerful to me, but also wary of what’s going on under the covers.

Sass also has the power to extend “placeholder” classes. Essentially invisible classes, in the format of %placeholder { }. This is useful for using internal naming that makes sense there but wouldn’t as actual class names.

Winner: Sass

Variable Handling

LESS uses @, Sass uses $. The dollar sign has no inherit meaning in CSS, while the @ sign does. It’s for things like declaring @keyframes or blocks of @media queries. You could chalk this one up to personal preference and not a big deal, but I think the edge here is for Sass which doesn’t confuse standing concepts.

Sass has some weirdness with scope in variables though. If you overwrite a “global” variable “locally”, the global variable takes on the local value. This just feels kind of weird.

$color: black;           
.scoped { 
  $color: white;
  color: $color;        
}                        
.unscoped {     
  // LESS = black (global)
  // Sass = white (overwritten by local)
  color: $color;          
}

I’ve heard it can be useful but it’s not intuitive, especially if you write JavaScript.

Winner: Tossup

Working with Media Queries

The way most of us started working with @media queries was adding blocks of them at the bottom of your main stylesheet. That works, but it leads to mental disconnect between the original styling and the responsive styles. Like:

.some-class {
   /* Default styling */
}

/* Hundreds of lines of CSS */

@media (max-width: 800px) {
  .some-class {
    /* Responsive styles */
  }
}

With Sass or LESS, we can bring those styles together through nesting.

.some-class {
  /* Default styling */
  @media (max-width: 800px) {
    /* Responsive styles */
  }
}

You can get even sexier with Sass. There is a really cool “respond-to” technique (see code by Chris EppsteinBen Schwarz, and Jeff Croft) for naming/using breakpoints.

=respond-to($name)

  @if $name == small-screen
    @media only screen and (min-width: 320px)
      @content

  @if $name == large-screen
    @media only screen and (min-width: 800px)
      @content

The you can use them succinctly and semantically:

.column
    width: 25%
    +respond-to(small-screen)
      width: 100%

Nested media queries are a fantastic way to work. Rumor has it Sass 3.3 will have more features to make this even more useful, including a way to make extend work within media queries which is currently impossible in both LESS and Sass.

Winner: Sass

Math

For the most part, the math is similar, but there are some weirdnesses with how units are handled. For instance, LESS will assume the first unit you use is what you want out, ignoring further units.

div {
   width: 100px + 2em; // == 102px (weird)
}

In Sass, you get a clear error: Incompatible units: ’em’ and ‘px’. I guess it’s debatable if it’s better to error or be wrong, but I’d personally rather have the error. Especially if you’re dealing with variables rather than straight units and it’s harder to track down.

Sass will also let you perform math on “unknown” units, making it a bit more futureproof should some new unit come along before they are able to update. LESS does not. There is some more weird differences like how Sass handles multiplying values that both have units, but it’s esoteric enough to not be worth mentioning.

Winner: Narrowly Sass

Active Development

I’m going to update these numbers since it’s been enough time since the original writing of this article.
05/16/12 01/12/13 06/25/13
Number of open issues on LESS 392 112 142
Number of open issues on Sass 84 83 110
Pending pull requests on LESS 86 10 5
Pending pull requests on Sass 3 7 11
Number of commits in the last month in LESS 11 84 2
Number of commits in the last month in Sass 35 14 14

None of that stuff is any definitive proof that one project is more active than the other, but it is interesting to look at stats. As I understand it, both of the leads work on the languages in whatever little free time they have, as they both have other major new projects they are working on.

LESS has been pretty actively lately, but now Sass has gotten much more active too, due to a core member getting to focus on it directly.

Winner: Tossup