Pretty image
Brian shows off some of the magic of Sass, a DSL for generating stylesheets.

I hate CSS.

Don’t get me wrong. The concept of CSS, where we keep our presentation separate from design, is great. CSS lets me do some amazing stuff in terms of presenting content to my visitors. But the markup language itself is just awful, and anyone with even a little programming experience gets the feeling that it’s a half-finished implementation.

If you want a border and a titlebar background to share the same color, you have to hard-code that value all over your stylesheet because CSS has no support for variables. If you want to share CSS style rules between multiple elements, you’re going to end up pasting those rules multiple times. If you want your unordered lists in sidebars to look different from unordered lists in your main content, you have to write long scoped selectors. It just doesn’t seem right, and now there’s a solution: Sass.

Sass is a DSL for generating stylesheets. It’s written in Ruby, but it generates standard CSS files that any web browser can understand. That means that you can take advantage of Sass whether you’re working with Rails, ASP.NET, Python, PHP, or static HTML.

How It Works

First, you need Ruby installed. On a Mac, you probably have everything you need, and if you’re on Windows you can snag the RubyInstaller for Windows. Sass is actually part of the Haml package, so to install it, you install the Haml gem. From a terminal, type

 gem install haml

That installs everything you need to work with Sass. Let’s try out a really simple example to make sure everything works.

Open up your text editor of choice and type in this code:

 h1
  color: red
 
 p
  line-height: 20px
  font-size: 14px

When you type this in, be sure to keep your indentations the same. In this example, the h1 and p selectors are not indented, but the lines below are indented with two spaces. You have to be consistent in your files and you have to be sure not to mix tabs and spaces in the same file. It sounds a little rigid at first, but there’s a reason for it which you’ll discover very quickly.

Save it as test.sass. Now drop back to the command line and type:

 sass test.sass > test.css

This generates a regular CSS file that looks like this:

 h1 {
  color: red; }
 
 p {
  line-height: 20px;
  font-size: 14px; }

So, Sass saves you from having to use opening and closing curly braces and semicolons. Mildly useful. Yes, but that’s just the very beginning. Let’s build something more complicated.

Rounding Corners with CSS3 and Sass

CSS3 makes it really easy to round corners on elements. In this example, we’ll use Sass and CSS3 to make a rounded callout box with a grey background.

The HTML markup for our callout box is a single paragraph tag wrapped by a div with the class of callout

 <div id="callout" class="rounded">
  <p>
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
  eiusmod tempor incididunt ut labore et dolore magna aliqua.
  Ut enim ad minim veniam, quis nostrud exercitation ullamco
  laboris nisi ut aliquip ex ea commodo consequat.
  </p>
 </div>

Basic Rounded Corners

In order to make it work in Firefox, Chrome, and Safari, you need to define multiple rules like this:

 border-radius: 5px;
 -moz-border-radius: 5px;
 -webkit-border-radius: 5px;

Let’s define a CSS rule with Sass that rounds the corners of any element that has the class of rounded.

 .rounded
  border-radius: 5px
  -moz-border-radius: 5px
  -webkit-border-radius: 5px

Notice that once again there’s very little difference, but we can take this and greatly improve it.

Using Variables

I always found it odd that CSS didn’t have support for variables. We use numbers and values so much when we design with CSS that it seems like a no-brainer. We’ve defined the corner radius three times in our previous example. Let’s use Sass’s support for variables to remove that hard-coded value.

 !radius = 5px
 
 .rounded
  border-radius = !radius
  -moz-border-radius = !radius
  -webkit-border-radius = !radius

There’s a slight syntax change here. You declare variables by using an exclamation point at the start of the line. You assign the value using the equals sign, and when you use the variable in your rule, you also use the equals sign instead of the colon.

This is wrong:

 border-radius: !radius

This is right.

 border-radius = !radius

With the radius stored in a variable, we’re free to tweak the value of the radius as we design.

Variables also support math. We could do something like this:

 !measure = 20px
 !radius = !measure / 4
 !font_size = !measure - 8
 !h1_size = !measure + 4

You can leverage this to easily define your font sizes and even your color scheme. Our callout needs a background color, so let’s define that as a variable and add it to our definition. We’ll also add a padding to the callout, which we can set to double the radius value.

 !radius = 5px
 !callout_background = #ddd
 
 .rounded
  border-radius = !radius
  -moz-border-radius = !radius
  -webkit-border-radius = !radius
  background-color = !callout_background
  padding = !radius * 2

Variables make it really easy to manage measurements and colors. But watch how we can take reuse to the next level.

Sharing Code with Modules

We’ve committed a bit of a sin with our HTML markup. We’ve tied the presentation to the content. Our rule applies the rounded corners to any element with a class of rounded, but really, classes in HTML aren’t supposed to expose the presentation details. Using a class of rounded is kind of like using a class of red_text. You may decide later on that you don’t want callouts to be rounded, or that you don’t want text to be red. You don’t want to have to go through your markup and change it all.

We can solve this problem with Sass by defining a module for the rounding rules which we can easily reuse wherever we’d like.

We declare a module by starting the line with an equals sign, and we place our rules beneath it. We then apply it by using the plus sign. Having done this, we can then change the style rule to apply directly to our callout element. Our Sass file looks like this now:

 !radius = 5px
 !callout_background = #ddd
 
 =rounded
  border-radius = !radius
  -moz-border-radius = !radius
  -webkit-border-radius = !radius
 
 #callout
  +rounded
  background-color = !callout_background
  padding = !radius * 2

We’ve now removed the need for the rounded class on the element and in the stylesheet.

Styling the Paragraph

Sass uses whitespace indentation to nest rules beneath selectors, but it also uses this indentation to scope selectors. With CSS, to apply a specific style to the paragraph within our callout section, we’d write this selector:

 #callout p

With Sass, we place the paragraph selector beneath the selector for the callout.

 #callout
  +rounded
  background-color = !callout_background
  padding = !radius * 2
 
  p
  line-height: 20px
  font-size: 14px

When we generate the CSS, the selectors will be properly generated. If you’ve ever needed to scope selectors within various regions, you can start to see how handy this can be.

Removing the Last Margin

Paragraphs have a default bottom margin, and in a callout box like this, it’s desirable to remove the margin from the last paragraph. CSS3 has a pseudo selector we can use for this.

 #callout p:last-child{
  margin-bottom: 0px;
 }

In Sass, you use the ampersand character to denote the pseudo class selector, like this:

 &:last-child
  margin-bottom: 0

We nest that below our paragraph selector and end up with a Sass file that looks like this:

 !radius = 5px
 !callout_background = #ddd
 
 =rounded
  border-radius = !radius
  -moz-border-radius = !radius
  -webkit-border-radius = !radius
 
 #callout
  +rounded
  background-color = !callout_background
  padding = !radius * 2
 
  p
  line-height: 20px
  font-size: 14px
 
  &:last-child
  margin-bottom: 0

When you convert that to CSS, you’ll get this:

 #callout {
  border-radius: 5px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  background-color: #dddddd;
  padding: 10px; }
 
  #callout p {
  line-height: 20px;
  font-size: 14px; }
 
  #callout p:last-child {
  margin-bottom: 0; }

Sass does proper descendant-selector creation, and even indents descendants to improve readability. Our colors are inserted, and our padding is multiplied correctly. Notice that even the unit of measure was preserved!

That’s just a small sample of what you can do with Sass, but imagine what you could do if you managed the entire stylesheet like this. You’d have code that’s easier to manage and maintain. If you’re interested in further optimization, you could use Sass to build your stylesheets and then run them through a compressor like YUI Compressor or similar tools as part of an automated build process.

The Future of Sass

If you’re used to the CSS syntax, you may not be that into this new whitespace-sensitive syntax. The Sass developers are well aware that the syntax could be a barrier to entry, and so they’ve begun work on SCSS, a new syntax that looks just like regular CSS, but adds in all of the Sass goodness. If you, like me, happen to love the regular Sass syntax, you can rest comfortably knowing that it’s not going away.

There are some other great features in the works for Sass, and you can follow those by watching the Haml project on Github.

Where to Go Next

If you want to play with Sass without installing anything, you can use a site I built called Rendera, which lets you work with Sass right in your browser. You’ll find some examples there too, including the one from this article.

Once you’re comfortable with Sass, you owe it to yourself to investigate Compass. Compass helps you design better stylesheets by providing a framework for composing stylesheets together. If you’re a fan of the Blueprint CSS framework, you can mix it into your existing stylesheets instead of altering your markup. That can make applying a CSS framework to an existing site many times easier. The best way to get started with Compass is to watch the great screencast on the Compass site.

Sass has proven to be an effective tool for me as a web developer. I don’t work without it anymore, and I’m sure once you give it a try you’ll feel the same way.

I can’t wait to see how you use it!

Brian Hogan has been developing web sites professionally since 1995 as a freelancer and consultant. He’s also built small and large web sites and web applications using ASP, PHP, and Ruby on Rails. He enjoys teaching and writing about technology, particularly web design and development. He is the author of Web Design for Developers: A Programmer's Guide to Design Tools and Techniques.