Tuesday, November 18, 2008

A Compass Primer

The goal of this post will be to help you install Compass and Sass and then learn the basics. When you are done, if you follow along, you will have a working stand-alone compass project. If you're looking to better understand what Compass can do for you, please read the compass introduction and then come back. If you plan to use Compass with Rails, Merb, or StaticMatic, there's specific installation instructions for each available on the wiki but for now, you can follow along without them.

Some Basic Prerequisites

  • Both Compass and Sass require you to have Ruby installed. If you don't have ruby installed, please do so now.
  • Please make sure you have rubygems version 1.3 or greater by running gem -v.
  • Using compass will require you to do some basic command line work. If you're not comfortable using the command line, you should probably pass on Compass for a while until we get more users and some IDE support, etc.

Installing Compass

$ gem sources --add http://gems.github.com/
$ sudo gem install chriseppstein-compass
You have successfully installed compass if you can perform this command:
$ compass -v
Compass 0.8.15
Copyright (c) 2008 Chris Eppstein
Released under the MIT License.
Sass, which is part of the Haml project, was also installed for you. Sass comes with two command line tools that you should be aware of:
  • sass - A sass compiler for single files and directories that emits css.
  • sass-convert - A sass translator for your existing css, less, sass, and scss files.
Both of these tools also operate on "stdin" for easy integration with other command line tools and GUIs.

Setting up your First Compass Project

We will now create a new project named "my_compass_project" based on blueprint. The contents of the project will be placed into the my_compass_project subdirectory of your current directory -- which will be created for you.
$ compass create my_compass_project --using blueprint --syntax sass
  directory my_compass_project/
  directory my_compass_project/images/
  directory my_compass_project/src/
  directory my_compass_project/src/partials/
  directory my_compass_project/stylesheets/
     create my_compass_project/config.rb
     create my_compass_project/src/screen.sass
     create my_compass_project/src/partials/_base.sass
     create my_compass_project/src/print.sass
     create my_compass_project/src/ie.sass
     create my_compass_project/images/grid.png
     exists my_compass_project/stylesheets
    compile my_compass_project/src/ie.sass
     create my_compass_project/stylesheets/ie.css
    compile my_compass_project/src/print.sass
     create my_compass_project/stylesheets/print.css
    compile my_compass_project/src/screen.sass
     create my_compass_project/stylesheets/screen.css

  *********************************************************************
  Congratulations! Your compass project has been created.

  You may now add and edit sass stylesheets in the src subdirectory of your project.

  Sass files beginning with an underscore are called partials and won't be
  compiled to CSS, but they can be imported into other sass stylesheets.

  You can configure your project by editing the config.rb configuration file.

  You must compile your sass stylesheets into CSS when they change.
  This can be done in one of the following ways:
    1. To compile on demand:
       compass compile [path/to/project]
    2. To monitor your project for changes and automatically recompile:
       compass watch [path/to/project]

  More Resources:
    * Wiki: http://wiki.github.com/chriseppstein/compass
    * Sass: http://sass-lang.com
    * Community: http://groups.google.com/group/compass-users/


  Please see the blueprint website for documentation on how blueprint works:

      http://blueprintcss.org/

  Docs on the compass port of blueprint can be found on the wiki:

      http://wiki.github.com/chriseppstein/compass/blueprint-documentation

  To get started, edit the screen.sass file and read the comments and code there.

  To import your new stylesheets add the following lines of HTML (or equivalent) to your webpage:
  <head>
    <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/print.css" media="print" rel="stylesheet" type="text/css" />
    <!--[if lt IE 8]>
        <link href="/stylesheets/ie.css" media="screen, projection" rel="stylesheet" type="text/css" />
    <![endif]-->
  </head>

As you can see from the output several new directories have been created, some sass files have been added already and they've even been compiled to css for you. Before we change anything let's verify that our project is working out of the box.

Create an HTML file

Let's create the following html file named index.html in the my_compass_project directory:

Now open index.html in your browser and you should see a nice looking H1 that is left justified within the centered 950px blueprint grid container.

A Quick Intro to Sass

As mentioned already, Compass is built on top of the Sass stylesheet language. Before we can style our webpage, we should review some Sass basics. Sass provides a much cleaner syntax than CSS for styling your webpages. But before we style our ours, let's review some of the basics of the Sass language. First and foremost, Sass allows you to use indentation to indicate a descendent selector, yielding style

Which generates two css rules that look like: This ability to scope selectors allows you to easily avoid the dreaded "CSS Spaghetti" where your styles and class names end up bleeding into areas where you'd rather they didn't. Have you ever wanted to name your colors so that you wouldn't have to remember the hex values or so that you could change them easily? Sass provides variables to which you can assign values and reuse them over and over again: Do you find recurring patterns for styles and copy and pasting them into different selectors? Sass provides a concept called a mixin that addresses this problem. You can define a mixin like so: And once you'd defined your mixin, you can "mix it" into any selector like so: Mixins can also take arguments, define rules for descendants, and even include other mixins: +clearfix is a mixin provided by the compass utilities module that makes sure the bottom of an element containing floated elements falls below the contained elements. These mixins can be used like so:

This ability to create abstractions using mixins is what makes Compass possible and what makes your life easier. Sass has many features that I cannot cover here, I highly encourage you to go read the Sass documentation to learn more.

Introduction to Blueprint

If you are familiar with the Blueprint CSS Framework, you can now use it just as you would have without compass. All of the Blueprint classes are defined and available to you. If you're not familiar with blueprint, I'll give a quick overview here:

Blueprint creates a 950px wide container that is divided into 24 units across. Each unit is composed of 30px of content space and 10px of gutter space. Using the +column mixin you can define an element as a column that is some number of units wide. Columns are floated left and new rows are created by this floating whenever an element would extend past the container bounds. For this reason, we have to tell the last element on a row that it is the last one so that it knows to remove the 10px gutter on the right side and fit into the current row. When a columns is 24 units wide it is implied that it is the last column for the row and so it is safe to omit the last argument from those column declarations. Columns can be nested in which case the nested columns must add up the the width of the containing column and each row of nested columns must end with an additional last option. Please see the wiki for a complete reference of the blueprint grid library.

Getting Semantic

However, the very reason that compass was created was to make it possible for us to avoid using presentational class names in our markup. So let's rip out a few things that we're not going to use to avoid enlarging our stylesheet unnecessarily.

Open up src/screen.sass in your text editor and change it to this:

This change removes the blueprint grid classes from our generated CSS, we don't need them because we're going to use the blueprint library's grid mixins with our semantic markup instead.

Let's briefly go over the changes we've made here:
  • First, we're only applying these styles to pages that have a body class of "blueprint". This is entirely optional, but as a best practice, I encourage you to always scope your styles by a body class or id so they don't appear where you intend them to.
  • We've taken out the generic +blueprint mixin that adds the entire blueprint framework and replaced it with +blueprint-typography which only styles our typography.
  • We've told the class .container that it is a blueprint container on body.bluprint pages.
The parts that didn't change:
  • @import directives make different sass libraries available to us. If those libraries have styles in them, those styles are added to our pages as is the case for the compass/reset.sass which will do a global reset to all pages that include this stylesheet. For more information on css resets, please read Eric Meyer's Post. It is also possible to selectively reset only certain pages, but that is outside the scope of this post.
  • the scaffolding import and the +bluprint-scaffolding call makes our page look nicer as we're first getting started, but soon enough we'll want to pull these out because the styles it provides usually get in the way of a fully styled website.
Now we update our CSS files by running the compass command line while in the my_compass_project directory.

$ compass compile
compile src/ie.sass
overwrite stylesheets/ie.css
compile src/print.sass
overwrite stylesheets/print.css
compile src/screen.sass
overwrite stylesheets/screen.css
Reload index.html and things should look exactly the same.

Setting up auto-updates

We'll be making a number of stylesheet changes going forward and having to run the compass command-line after each edit gets tedious. So compass provides a "watch" mode that will monitor your project for changes and recompile your stylesheets automatically. In your project directory run the following command:

$ compass watch
If you encounter an error, the details will appear at the top of your webpage.

Styling your First Page

Now it's time to add some content to our page and style it. Let's update the container element in our index.html to the following: We will now style this page to have a header, footer, sidebar and primary content area using blueprint grid mixins. Open src/screen.sass in your text editor change it to the following: These sass mixins assign blueprint styles to our page that causes it to be laid out nicely. After saving, the css should have been automatically compiled for you. Go ahead and reload your index.html. It looks pretty good, but I think the header needs a little cleanup so we'll apply some basic styling as well as some compass utilities to it: First, let's pull in the compass utility library by adding an import: @import compass/utilities And then amend the #header style rules like so: You'll notice we've floated the h1 left and the site actions right. I've also told the site-actions list to be a horizontal-list, which is a very handy utility mixin provided by compass. Reload the page, and I hope you'll agree that looks pretty decent. Let's take a look at the css we've generated just for giggles:

Conclusion

Well, you've seen how to style a page using Sass and Compass. We've only just scratched the surface here. I hope this was enough to get you started. From here you should go read the wiki, and ask questions on the mailing list if you get stuck.

See Also

If you found this post confusing (or maybe slightly out of date), there is a very nice blog post here on how to get compass running and it explains some of the basics.

13 comments:

csbartus said...

excellent!
finally this give us a html/css framework + plugins.

separately jquery can be mixed in and the dhtml fw/plugin architecture is ready.

that's awesome !!!!

Unknown said...

something's broken
...or I'm doing something actively stupid.

I updated my currently installed Haml and it only goes up to 2.0.9.
Cloning a fresh copy (per your git command) gives the same version.

Compass of course blows up on install...requiring Haml version 2.1.0.

what am i doing wrong.

Unknown said...

We had the same Haml version issue - just clone the latest haml gem and build ($ rake gem) and install locally and you should be good to go.

Side note - anyone know how to turn on line numbers in the css output? We haven't been able to get that working yet.

Andrew Leer said...
This comment has been removed by a blog administrator.
oscarBravo said...

I could be doing something very stupid, but when I follow these instructions I get this:

body.blueprint { }
body.blueprint body { line-height: 1.5; font-family: Helvetica Neue, Arial, Helvetica, sans-serif; color: #333333; font-size: 75%; }

Obviously "body body" doesn't work as expected...

oscarBravo said...

Figured it out: +blueprint-scaffolding and +blueprint-typography need to be at the top level of the stylesheet, rather than below "body.blueprint".

Mark A. Richman said...

Can someone please translate index.html in this example to index.haml?

chris said...

@Mark, there's a command line utility called html2haml that comes with haml.

chris said...

@oscarBravo I've updated the gists to match some changes that were made to the +blueprint-typography mixin.

Doug Holton said...

Why in all your examples to you repeat the display: twice with different values for the same item:

#site-actions { ... display: inline-block; }

#site-actions { display: block; }

Doesn't that just overwrite the display setting?

chris said...

@doug

Yes it does, but it has a side-effect of causing ie6&7 to gain layout.


In compass, gaining layout can be applied to elements by using the +has-layout mixin.

Aldo Escudero said...

Hi everyone. First of all, I would like telling that I am newbie on compass and I have been told that there's a mixin for working with navbars. I would really appreciate any help on this. (Sorry, if this wasn't the place for posting these kind of questions).And thanks in advance if someone can help me.

chris said...

@aldo Please contact the mailing list for support.