Getting Started with Sass
Issue № 340

Getting Started with Sass

CSS’ simplicity has always been one of its defining, most welcome features. CSS style sheets are just long lists of rules, each consisting of a selector and some styles to apply. But as our websites and applications get bigger and become more complex, and target a wider range of devices and screen sizes, this simplicity—so welcome as we first started to move away from font tags and table-based layouts—has become a liability.

Article Continues Below

While some have offered proposals on how to fix CSS—adding constants or variables, for example—none have been implemented by any browser manufacturers. And even if a browser did implement a newer, better, extended CSS, it could be years before the new syntax is supported well enough in all browsers for it to make sense to use it.

Fortunately, a few years ago developers Hampton Catlin and Nathan Weizenbaum proposed a better way to maintain a complicated stylesheet. While browsers aren’t ready for a new CSS, Catlin and Weizenbaum realized they could go ahead and design a new style sheet syntax with features to help make their increasingly complex CSS easier to write and manage, then use a preprocessor (a program that runs on your computer or server) to translate the new smart syntax into the old, dumb CSS that browsers understand.

The new stylesheet syntax they developed is called Sass, which stands for “syntactically awesome style sheets.” The original versions of Sass looked very different from regular CSS; there were no curly braces, and properties had to be indented with a specific number of spaces or else the compiler would raise an error. Programmers (who are used to learning new syntaxes, and enjoy pain) didn’t mind this so much, but for regular web designers it was different enough from the CSS they knew that most of them stayed away. There was a practical issue as well: because Sass’ indented syntax wasn’t compatible with regular CSS, it was difficult for people with large existing websites to start taking advantage of it without spending time converting their old code to Sass.

So in Sass 3.0 the developers introduced a new, more CSS-like syntax called SCSS (or “Sassy CSS”). SCSS is what the nerds call a “strict superset” or “metalanguage” of regular CSS, which means anything that’s valid CSS is also valid SCSS. In other words, all of your existing style sheets should work with the Sass processor with no problems, allowing you to get your feet wet by playing with some Sass features without learning every facet of the new language.

Unlike regular CSS, Sass’ SCSS is a real scripting language, with expressions, functions, variables, conditional logic, and loops. You don’t have to use all of these features to get some benefit out of Sass, but they’re there if you need them, and on large projects they can make complex or repetitive CSS much easier to write.

For this article I’m going to demonstrate a few basic moves, to give you an idea of what’s possible with Sass and SCSS in your designer’s utility belt. At the end I’ll recommend some links and books to check out when you’re ready to explore further.

To keep things as clear and simple as possible, most of my examples below focus just on the SCSS code, not the compiled CSS output. The best way to understand how Sass works is to try it for yourself, by writing some SCSS styles and seeing what comes out. That said, all of my source code examples are available on GitHub for your reference, along with their compiled CSS output, so you can see how all of these neat new features translate into usable style sheets.

Getting started#section2

Sass is written in Ruby, and distributed via the Ruby package manager, RubyGems. If you’re already familiar with Ruby (and your computer’s command prompt) you can find instructions for installing and running the Sass gem on the Sass website.

For those who are less handy on the command line, or who just want a fast and easy way to work with Sass, there’s Scout, an AIR app available for Mac and Windows that comes with Ruby and has the Sass compiler built in.

Both the sass command line tool and the Scout app work by watching your SCSS style sheets for changes as you work on them, then automatically compiling them into regular CSS when you save. The directory where your Sass files live is called the input folder. Your processed CSS files are saved to the output folder. These folders can be nested inside one another; in fact, a typical pattern is for the input folder (which I usually call “scss,” though you can name it whatever you like) to live inside of your site’s regular stylesheets folder, like so:

my_project/
  index.html
  css/
    main_style.css
    scss/
      main_style.scss 
      _mixins.scss
      _colors.scss

In my scss folder above, the files whose names start with underscores are called partials. As the name would imply they contain “partial” style sheets, chunks of SCSS code to be imported into one of your main SCSS files. I’ll talk more about partials in a moment, but now you know where they live.

Use partials to organize your code#section3

CSS already provides the @import directive for linking to additional, external style sheets, and some developers like to use it to break up a large project’s styles into smaller logical chunks. For example, our main_style.css file might contain nothing but @import statements linking to a bunch of page-specific style sheets:

@import url('/shared/global.css');
@import url('/pages/home.css');
@import url('/pages/blog.css');

This isn’t considered the best practice however, because each of these imports is one more file that has to be requested and loaded by the browser, which can make your site load more slowly and will definitely lower your YSlow and Google Page Speed scores.

Sass helps out by letting you break large style sheets into partials. You still refer to them using the @import directive (in a new, briefer form), and when your SCSS files are processed, the contents of the partial are inserted directly into the output CSS. (Importing a URL works the same way it does in regular CSS.)

@import 'shared/global';
@import 'pages/home';
@import 'pages/blog';

The result is one file containing all of your styles. Sass can also automatically minify its CSS output, stripping out unnecessary white space or line breaks to optimize loading times.

There is one catch. Partials are a special kind of SCSS file, not meant to be used as regular stylesheets. Any code you put into one must be @import-ed into a stylesheet to be used. Partials’ filenames must start with an underscore—for example, the pages/home partial loaded above would actually be named pages/_home.scss. (These paths are always relative to the current file.) The underscore is how the Sass compiler knows that a file is a partial, and therefore shouldn’t be compiled into a fully-fledged CSS sheet. But given the purpose of a partial is to organize your code into logical chunks, this seems a fair trade-off.

Don’t repeat yourself#section4

Now that our style sheets are better organized, let’s try to make them less repetitive.

One of Sass’s nicest features is nested rules. In a regular CSS file, rules must be listed sequentially, and every rule’s selector must include all of its elements:

body.home .media-unit {
  border: 1px solid #ccc;
  background-color: #fff;
}
body.home  .media-unit .right {
  border-left: 1px solid #ccc;
}
body.home .media-unit .right h1 {
  font-size: 24px;
}

Apart from being really, really repetitive, this code doesn’t do anything to help us understand how the HTML elements we’re styling relate to each other. With nesting, we can write SCSS code that is both less redundant and easier to follow:

body.home {
  .media-unit {
    border: 1px solid #ccc;
    background-color: #fff;
    .right {
      border-left: 1px solid #ccc;
      h1 {
        font-size: 24px;
      }
    }
  }
}

After processing this will result in the same CSS as above. Unfortunately, the shorter syntax won’t make your CSS files any smaller or load any faster. But nesting will help keep your code clean, logical, and well-organized, which should also make it easier to manage over time.

Another cool nesting trick: Sass allows you to nest media queries inside other rules, making it easier to see which styles are applied to a given object on your page:

.container {
  width: 940px;  // If the device is narrower than 940px, switch to 
  // a fluid layout
  @media screen and (max-width:940px) {
    width: auto;
  }
}

When processing this file, Sass knows how to convert this back into valid CSS, copying the .container selector inside the media query like so:

.container {
  width: 940px;
}@media screen and (max-width:940px) {
  .container {
    width: auto;
  }
}

Variables#section5

Sass variables are great for two reasons. First, and most importantly, they make code easier to change by reducing duplication. But they also allow you to assign names to special property values like colors, which helps you understand the intent behind a given style.

At Typekit a number of elements in our UI use our signature green color, #99cc00, or “Typekit green” for short. This color appears hundreds of times in our CSS, used on everything from buttons to headline colors, such that if we ever changed our brand colors away from Typekit green it would be a lot of work to change every instance. By using variables instead of the raw hex code, it’s easy—just change the variable (which you can define at the top of your stylesheet, or even in a partial) and the new color appears everywhere, instantly. You can even set variables to other variables, which helps keep your style sheets semantic:

$typekit-green: "#99cc00";
$typekit-link-color: $typekit-green;a {
  color: $typekit-link-color;
}

You can assign almost any kind of value to a variable; apart from color hex values, they’re especially good for font-family stacks:

$sans-serif-font: 'ff-dagny-web-pro', 'Helvetica Neue', Arial,  
Helvetica, 'Liberation Sans', sans-serif;
$serif-font: 'ff-tisa-web-pro', Georgia, Times, serif;.banner h1 {
  font-family: $sans-serif-font;
}

Mixins#section6

Mixins are reusable sets of properties or rules that you include, or “mix,” into other rules. You define them using the @mixin keyword, and include them using the @include keyword.

In this example, I’m telling Sass to apply all of the style properties contained in the highlighted-bold-text mixin to all of the span elements inside .result-with-highlights

$highlight-color: #ffa;@mixin highlighted-bold-text {
  font-weight: bold;
  background-color: $highlight-color;
}.result-with-highlights {
  span {
    @include highlighted-bold-text;
  }
}

Once you’ve defined a mixin, you can reuse it anywhere else in the same file. Here I’m saying that elements with a class named highlighted should also have the color and font weight properties specified by the mixin:

.highlighted {
  @include highlighted-bold-text;
}

This is really useful for applying new CSS3 properties to elements, while ensuring wide cross-browser compatibility via vendor prefixes and fallback stacks. In regular CSS, vendor fallbacks can be annoying to use because they’re so verbose, which leads to a lot of boring copy-and-pasting. Sass mixins let us use new kinds of styles in a bulletproof way without writing a lot of code.

Here I’ve defined a mixin that applies 4px rounded corners to an element, using vendor-prefixed properties for WebKit, Firefox, and IE, followed by the standard border-radius property from the CSS3 spec. I’ve also defined the corner radius as a variable so it’s easier to change later on:

@mixin rounded-corners {
  $rounded-corner-radius: 4px;
  -webkit-border-radius: $rounded-corner-radius;
  -moz-border-radius: $rounded-corner-radius;
  -ms-border-radius: $rounded-corner-radius;
  border-radius: $rounded-corner-radius;
}.button {
  @include rounded-corners;
}

Mixins can also contain whole nested rules, not just properties. Here is a version of the familiar clearfix CSS hack implemented as a Sass mixin:

@mixin clearfix {
 // For modern browsers
  &:before,
  &:after {
    content:"";
    display:table;
  }  &:after {
    clear:both;
  }  // For IE 6/7 (trigger hasLayout)
  & {
    zoom:1;
  }
}.group {
  @include clearfix;
}

The ampersand (&) selector is a Sass convention that means “this element.” When this code is compiled Sass will replace all the & symbols with the current selector, in this case .group.

Making stylesheets smarter#section7

Using mixins to apply simple styles is cool, but what makes mixins awesome is that they can take arguments, just like a function in JavaScript or PHP. And you can use them in combination with more advanced features like expressions and functions to go far beyond organization to implement some great, complex styles.

Grid layout systems are a great application for Sass scripting. There are a lot of ready-made 960px CSS grid systems out there, but most of them require you to add non-semantic class names to your code. Not to mention the fact that to use one of these grids, you have to load all the CSS for the entire system, even if you only plan to use a few standard unit sizes.

For our final example, we’re going to implement a simple 12-unit grid in Sass. Rather than define class names for each grid unit, we’ll create a mixin that will apply the correct width and margins to turn any element into a unit of our grid.

First, we need to set up our column and gutter widths as variables:

$column-width: 60px;    // 12 columns = 720px
$gutter-width: 20px;    // 11 gutters = 220px

Next we’ll need Sass to do some math for us. A unit of our grid will span a certain number of columns, plus all of the gutters between those columns. To calculate the width, we’ll use the following formula:

width = (column width — span) + (gutter width — (span – 1))

Now we can write our mixin. Unlike the examples above, this mixin will take one argument—the span—which will be passed into our mixin as a variable. Each grid unit will be floated left, and to maintain the 20px gutter between columns, each unit will have a right margin equal to the gutter width:

@mixin grid-unit($span) {
  float: left;
  margin-right: $gutter-width;
  width: ($column-width * $span) + ($gutter-width * ($span - 1));
}

Simple, right? But there’s a lot of power in those few lines of code. We can implement a basic two-thirds layout with a main content area and a sidebar very simply, using some more semantically-named classes and our Sass mixins:

.container {
  @include clearfix;
  @include grid-unit(12);
  float: none;
  margin: 0 auto;
}

.main-content {
  @include grid-unit(8);
}

.sidebar {
  @include grid-unit(4);
  margin-right: 0;
}

As valuable as this is—and I use some version of this grid calculator mixin on every project I work on nowadays—this just begins to scratch the surface of what’s possible with Sass. 

Sass’ support for basic math expressions help make it much easier to craft adaptive fluid-width layouts. Here I’m using Ethan Marcotte’s responsive-width formula to create a more responsive version of my basic grid above. Sass doesn’t convert between CSS units unless specifically asked to, so I’ve wrapped my formulas in Sass’ built-in percentage() function:

.container {
// result = target / context
  width: percentage(940px / 960px);  .main-content {
    // This is nested inside of .container, so its context is 940px
    width: percentage(620px / 940px);
  }  .sidebar {
    width: percentage(300px / 940px);
  }
}

There are also functions for transforming and adjusting colors—you can make colors darker or lighter, or adjust saturation or alpha transparency, right within your style sheet:

$base-link-color: #00f;
a {
  color: $base-link-color;
}
a:visited {
  // This reduces the lightness of the color (in HSL terms) 
  // by 50%, leaving hue and saturation alone
  color: darken($base-link-color, 20%);
}figcaption {
  // Generates an rgba() color value with 50% opacity
  background-color: transparentize(#fff, 50%);
}

And if those functions aren’t enough you can define your own, and share and reuse them across projects as a simple partial. Check out the full list of built-in SassScript functions for a taste of what’s possible.

What’s next?#section8

The official Sass website is full of useful information, including a complete reference guide to the SCSS language. One thing you may find useful right away is this list of available SCSS text editor plugins, offering syntax highlighting and other useful tools for writing Sass code in your editor of choice.

In addition, Sass creator Hampton Catlin is currently finishing up an in-depth guidebook to Sass for the Pragmatic Programmers, which you can buy and read today through Pragmatic’s Beta Books program.

Beyond the core Sass language, there’s also Compass, a library of SCSS functions and patterns developed by Chris Eppstein, with built-in support for Eric Meyer’s CSS reset, the Blueprint grid system, plus tons of CSS3 and typographic effects. Its authors have called it “jQuery for stylesheets,” which is a pretty apt description. If you’re using the Scout app, the Compass framework is already installed. Otherwise, you can find instructions for installing and using it on the Compass website.

About the Author

David Demaree

David Demaree has been designing and building web sites since the 1990s. He currently serves as senior product manager for Typekit at Adobe and is the author of Git for Humans, published by A Book Apart. You can read his thoughts about software, food, coffee, and more on Twitter and Medium.

24 Reader Comments

  1. Excellent thing, minus only that it will be necessary for a long time to adapt, in order to freely practice to write code in Sass, even for the skilled web designer.
    But judging from the article — Sass is a worthy replacement of CSS in web design, the future of this technology exists.
    Easier syntax, logical structure and the possibility of using variables provides an excellent opportunity for developers and can significantly speed up the writing and editing CSS files.

  2. Good to see this topic tackled by ALA. I think of the two I prefer the Less syntax, but CSS preprocessing is definitely catching on either way.

    Two things I notice: I don’t think the @import syntax is new — when you reference local stylesheets you don’t need to use “url()” even in regular CSS.

    When you describe the @clearfix mixin, you @include it later as “clearFloats” — might confuse some people so I thought I’d point it out.

    Thanks for writing!

  3. I am so happy to finally see a Sass article on ALA! It adds incredible control over stylesheets that just can’t be done with regular CSS.

    Lately I have been enjoying building advanced tools with Sass and have found it to be far more extensible than anything else. The convenience of not having to use an external calculator, color schemer, modular scale, you name it is invaluable. Not to mention the robust frameworking capabilities Sass provides that allow the logic of styles to work beyond predefined values.

    Great article! Thanks for writing.

  4. Thanks for commenting! The @clearFloats@ thing is definitely a mistake; we’ll fix it.

    As for @@import@, I just tested a import statement without @url@-less in plain CSS (in Safari 5.1) and you’re right: @url@ is no longer required. Good to know, though I’m interested to know what browsers support this form of the import syntax. One advantage to the classic @@import url@ is that I know it’ll work everywhere.

    Sass always prefers to use @url@ for external CSS files. The main difference between @url@ and no-@url@ in Sass is that the preprocessor will check the ones with no @url@ to see if they might be Sass partials, whereas @urls@ are always assumed to be external. (They’re also always assumed to be correct syntax—you don’t need quotation marks inside your urls in CSS, so Sass doesn’t include them, but if you include them yourself Sass doesn’t take them out.)

  5. I’ve really taken to the idea of Sass and Compass and think they will make a huge difference. One cool thing I didn’t see mentioned is the ability to put robust comments in your .scss and strip them out for production stylesheets.

    Looks like the CMS has expanded the ampersand for referencing the parent. Looking at Sass’s documentation, I see the syntax as “&:property” not “&:property”

  6. bq. Looks like the CMS has expanded the ampersand for referencing the parent. Looking at Sass’s documentation, I see the syntax as “&:property” not “&:property”

    Fixed this morning. Thanks!

  7. I loved reading this post, it conveys the essence of Sass quickly and I must admit, I am very tempted to pick up this technology. When it comes to CSS, even something simple like CSEdit is so welcome because we NEED ways to manage CSS. It looks to me like Sass may be the way forward, or as Pat Metheny might say, “The Way Up”.

  8. My main stumbling block with SCSS is that I need to check all SCSS and compiled CSS into version control and ensure all developers (including server-side developers who want to make a quick change) whether freelance, internal or external, use SCSS and have Ruby or Scout installed to compile. Otherwise, merging their changes back into the original SCSS is a nightmare.

    My other option is to combine and minify all CSS and JS server-side on deployment, which is much simpler and still allows for multiple stylesheets and comment stripping.

  9. As with all new technologies, there some caveats with SCSS that can require work-arounds. This largely depends on the environment that you are working in and how your directories are structured (eg Ruby scaffold). While this article provides a good introduction to SASS, it would be nice to have a follow-up article describing some it’s technical limitations.

  10. I see clearly the advantages, but I’m reluctant to make the leap. In the case of JQuery, Javascript’s de-facto-but-still-closed standard, there is at least the justification that browsers interpret Javascript quirkily (I see JQuery as a browser-standardization layer). That’s not the case with CSS. I think the real problem with CSS is that developers underestimate it and get frustrated too quickly. CSS is all about organization rather than rules. For example, if you’re willing to use multiple classes there is no reason for lots of repetition in the style sheet.

  11. Does SASS have any advantages over LESS (or vice versa)? I see both mentioned quite a lot but I’m not too sure which is best to use.

  12. To me this seems to be another unnecessary layer to accommodate poorly structured markup. Surely its better to learn how to do something right than introduce a blanket to smother your mistakes.

    I agree that Viortol’s comments on JQuery. JQuery brings something to the party (browser standardisation for one thing) whereas SASS just masks bad structure.

  13. Great article and very informative. I wasnt crazy about it at first but after reading the diffrence, I migt just utilize it. Keep up the good work, cheers mate !

    Tre

  14. The right thing I am looking for, something rule about @include and nesting for me is quite usefull. TKS.

  15. I was very encouraged to find this site. I wanted to thank you for this special read. I definitely savored every little bit of it.
    Ealing Taxi

  16. i really dont get sass,, it can be just me but sass is one of those things which you read only for information but the truth is you dont really use them in your daily routine..
    its just making your are changing the face of our beloved CSS. it can help you for very big apps, but common for a small size website you just write 100 lines of css and taht will do you.
    But again its just me thinking dumb.. 🙂

  17. Thanks for the great article. I wanted to give you a heads up, and maybe it’s changed since the article was written that the quotes around your HEX values are outputting as well.

    From your example:

    $typekit-green: “#99cc00”;
    $typekit-link-color: $typekit-green;
    a { color: $typekit-link-color; }

    Looks like:

    a { color: “#99cc00”; }

    Which is throwing errors in webkit. (Have not tested other browsers).

  18. People should never forget that while using a pre-processor is great and can (will) save you a lot of time, it will only be as useful as your level of pure CSS knowledge.

    I’ve seen people replicating the whole DOM tree in SASS and while it reads very easily, it gives a horrible, specific and slow selector output.

    My advice would be to dive really deep into CSS, get your hands dirty, make a lot of mistakes and when you’re REALLY comfortable with it: use a pre-processor of your liking!

  19. After initially dabbling with LESS I quickly moved to SASS and have now been using it for a while and would never look back! A colleague asked me to explain how it works earlier, this article swiftly clarified things!

  20. In your example you use this code.

    .container {
    width: 940px;
    @media screen and (max-width:940px) {
    width: auto;
    }
    }

    Why not just use the max-width property here? No SCSS needed for this. Don’t over complicate things.

    .container {
    max-width: 940px;
    }

    Or is there a difference I haven’t seen?

  21. This is awesome! I’ve really been meaning to be able to learn how to organize my CSS and manage it better, and have wanted to start with a preprocessor… It looks like SASS will be it! Thank you David!

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA

I am a creative.

A List Apart founder and web design OG Zeldman ponders the moments of inspiration, the hours of plodding, and the ultimate mystery at the heart of a creative career.
Career