Compass, the 960 CSS framework, and Semantic Markup

Posted on by in Web

Finding your way to meaningful grid layouts using the Compass framework

My problem: Grid layouts – crazy, sexy, cool. Presentation classes in my semantic markup – neither sexy nor cool, and arguably crazy.

These days I can’t help but notice a burgeoning awareness regarding seasoned typographical principles and practices and lively discussions around the best way to bring these ideas and procedures to bear in the realm of web design. One area of these discussions that dovetails with my own interests is the subject of grid layouts. Grid systems are the architectonic foundation of a well structured and holistically interrelated design. They originated during the reign of the International Typographic Style, a primarily Swiss graphic arts movement which occurred after World War II. Grid layouts were cultivated and matured in the hands of such legendary designers as Emil Ruder and Josef Müller-Brockmann, acknowledged masters of simultaneously presenting information in a functional and stylistic manner. As web designers, I feel we should constantly strive for these same goals – the presentation of information in a readily understandable way, yet also striving for an elegance in our presentation. Grids can help us accomplish this goal.

Over the past few years much headway has been made in cultivating an online consciousness of Grid Systems. Khoi Vinh and Cameron Moll have shown us the benefits of using grid systems for web layouts, and Antonio Carusone from AisleOne has recently pieced together the awesome grid oriented hub, The Grid System. Further, a number of CSS based grid frameworks have been popping up on the scene. Those that have much traction in the blogosphere–Blueprint, YUI Grids, 960 grid system–are only the tip of the iceberg.

I’ve been interested in experimenting with one of these frameworks for a while, but I have a single nagging concern with the way they are structured. All of the frameworks I have looked at use CSS class definitions which possess names that reek of presentational concerns. For example, Blueprint requires class names like “span-7 last” or “span-8”; 960 favors the equally presentational “grid_1 prefix_1” or “grid_7 alpha.” I just can’t get on board with this approach. I’m a firm adherent to notions of lean, minimal, and semantically vaible (X)HTML markup. The web development community has made great strides in separating out presentational concerns from the meaning inherent in well-crafted (X)HTML, divorcing the two orthogonal axes of style and semantics. And while I am a firm believer in the power of the grid to unify these two axes, as has been so well exhibited in the world of print, I cannot support said unification if it comes at the cost of reintroducing presentational markers into our markup – even something as ostensibly innocuous as a ‘mere’ presentational class.

So, where does that leave us? Is it possible to get the best of both worlds? Can we simultaneously develop semantic markup while leveraging those tried and true grid layout principles common enough to be packaged into a framework?

A potential solution to my problem: Compass – crazy? sexy? cool? To be determined…

Much to my pleasure, I am alone in neither my conviction nor my desire. Enter Compass, a ruby based application which provides Sass based APIs to many of the most prominent CSS frameworks, including those concerned with providing grid layouts. Compass sits on top of Sass, a domain specific language (DSL) for programmatically crafting CSS. The power of Sass derives from the fact that it is a real programming language, replete with all the benefits of such a thing: pragmatic tools such variable declarations, control structures, and method invocations, as well as more theoretical, but no less useful, concepts like abstraction, DRY-ness, encapsulation, modularity, and code re-use. I’ll admit, I’m new to Sass, having used it only superficially on a small work project. I have barely scratched the surface of its capabilities. And while some feel its application fails when applied to large scale projects, I can’t help but favor the programmatic benefits Sass brings to the table given my software engineering background.

Armed with Sass, developers can effectively write small libraries of code which will ultimately be translated into CSS. And Compass provides them with a mechanism for collecting these Sass libraries together and incorporating multiple APIs to into their own projects.

So, how does Compass help preserve semantic markup?

One of Sass’s most compelling features is known as a ‘mixin’. A mixin is a small module of Sass code, defined but once, that can be included into a Sass file and then referenced throughout. You can see where this is going. Imagine that in your application’s Sass file, you can gain access to, for example, 960’s grid layout API. You can ‘mixin’ these snippets of Sass code directly into your own semantic class definitions forgoing the need to use 960’s presentational class names anywhere in your (X)HTML. In short, Compass grants you the power to marry a tightly structured grid-layout with the beauty of lean, semantic markup. Pretty nifty, no?

So I decided to put all this to the test. I needed to learn more Sass, I wanted to play with the 960 grid system, and I wanted to vet Compass’s claim that it can help you eat a grid-layout cake iced with sugary semantic goodness. Follow along if you will…

Sussin’ the Solution: My first Compass-960 project

Installing Compass and the 960 plug-in

Since I already had Ruby and RubyGems installed, I was ready to start straight away with the installation of Compass.

First, I installed the bleeding edge of Haml, which includes Sass:

$ git clone git://
$ cd haml
$ rake install

I verified my Sass installation:

$ sass -v
Haml 2.1.0

Good to go. Next, I installed Compass and the 960 plug-in:

$ gem install chriseppstein-compass
$ gem install chriseppstein-compass-960-plugin

Creating a Compass-960 website project

Time to create a template Compass-960 project:

$ compass -r ninesixty -f 960 the_obscurantist

Now I had my template project, which comprised:

$ find the_obscurantist/

Out of the box, the 960 plug-in produced two Sass files, grid.sass and text.sass. These two files mirrored the CSS files that come with the 960 framework, 960.css and text.css respectively. Whe I inspected the *.sass files, I noticed they already contained code to get me up and running with a basic 960 grid layout.

At this point I took some time to finagle things into a state commensurate with my overall goal – the elimination of 960’s presentational class names. First, I wasn’t interested in 960’s typography, so I ditched text.sass and text.css. Second, I also ditched grid.sass and grid.css, because those files provide access to styles designated with presentational class names, for example: ‘.container_12’, ‘.grid_4’, etc. Next, as learning exercise, I converted my variation on Eric Meyer’s CSS reset to Sass. Finally, I set up an application.sass file, being sure to include the 960 API and Compass’s clearfix module.

@import compass/utilities/general/clearfix.sass
@import 960/grid.sass

Ok, cool. I had some Sass files, but where were my CSS files? Simply enough, I had to run Compass to generate them.

$ compass
   exists stylesheets
  compile src/application.sass
identical stylesheets/application.css
  compile src/reset.sass
identical stylesheets/reset.css

Manually regenerating your CSS files everytime you make a change is burdensome. Compass can be run as a process that detects changes to your source files and automatically regenerates your css. I’ve found that leaving this process running in its own shell is useful so I can keep an eye on the Sass log for parsing errors.

So I ran compass as a daemon to forgo manual re-generation:

$ compass --watch

Great. Setting up a basic Compass project went off with out a hitch. I added in the remaining requisite files — an index page and the jQuery javascript library — and was ready to… Oh wait, what am I building?!

Using 960’s handy design resources to brainstorm ‘The Obscurantist’ daily newspaper

Because my whole endeavor was motivated by an intuitive yearning for transparent and easily interpretable semantic information, I decided to tip a hat to my favorite muse, Bittersweet Irony, and design a newspaper that had but one purpose – proffering the opaque and the impenetrable. Enter, The Obscurantist! As newspapers traditionally adhere to very strict grid layouts, the Obscurantist would allow me to learn the basics of the 960 framework.

In my view, some of the most useful resources provided by the 960 framework are the sketchsheets and grid templates. The sketchsheets were great for quickly thumbnailing rough ideas.

Here’s an example of a sketchsheet, marred only by my attempt at artistic expression:

Example usage of the 960 frameworks 16-grid sketchsheet

Example usage of the 960 framework

16 columns was overkill, so I decided to fire up Illustrator and utilize 960’s Illustrator 12-column grid template as a background layer to help me lay out my page design. (960 comes with a range of templates catering to the most prominent graphics programs.)

Here’s the final design:

The Obscurantist Illustrator layout using a 960 template file as background layer

The Obscurantist Illustrator layout using a 960 template file as background layer

Mark It Up

The next step was converting my design to semantic and valid XHTML. This post is already long enough, so I won’t bore you with the details. Suffice it to say, I tried my best not to let presentational concerns influence my markup. By keeping things as semantic as possible, I set the stage for seeing how well Compass would facilitate leveraging 960’s layout structure in spite of the framework’s presentational class names. Feel free to pop open firebug and check out the The Obscurantist’s markup for yourself.

Stylin’ with Sass, 960 degrees o’ heat, straight sexified son!

The next step was to implement my 12-column grid layout in application.sass. As I had already designed The Obscurantist in Illustrator using the 960 grid template as a backdrop, coding up the grid was very straight forward. It turns out I can count to twelve, so I was in good shape. I’ve included the relevant aspects of application.sass below. Read it over, and below I’ll explain Compass’s 960 API in more detail.

@import compass/utilities/general/clearfix.sass
@import 960/grid.sass

/* ...omitted for brevity... */






  • ‘+grid-container’ establishes the overall 960px wide centered layout
  • ‘+grid(m, n)’ assigns an element a width based on the number of columns(m) it should take up with respect to a number of total colums(n)

Keen readers will notice that while the 960 grid system supports only 12 and 16 column layouts, +grid(m,n) is a method call which supports any number of columns. That’s right, Compass provides a completely customizable 960 pixel wide layout. The various column widths are calculated when Sass generates your CSS. (More on this below.)

So what about this ominous sounding “Alpha” and “Omega” business? As it happens, the 960 framework defines a gutter of 20px, each neighboring element contributing a 10 pixel margin to the overall gutter. Therefore, there will be a 10 pixel margin on the left and right hand sides of the overall grid container, constituted by the left side of the first element in a row and the right side of the last element in a row. (Check out The Obscurantist in Firebug for a better understanding.)

But, what happens if you are nesting grid elements? In that case you don’t want the child to re-contribute 10 pixels of outside margin, as the parent element already took care of this. What do you do? Simply demarcate the left most nested element as the ‘Alpha’ and the right most nested element as the ‘Omega’. Doing so will remove the outside margins and your grid layout will remain locked in place.

One additional note, the container element has had a clearfix applied to it, so that it will expand to
contain its floated child elements. This allowed me to attach 960’s 12-column grid image as a background to ensure my layout exactly matched my mockup.

The end has come: Sexiness – attained. Coolness – attained. Craziness – Why not?

The end result – The Obscurantist. You can toggle the 12-column grid background using the button in the upper right-hand corner.

I’m sold. Compass successfully allowed to me attain my goal: overall clean, minimal, and semantic markup and a rigid adherence to an underlying grid-system.

Finally, the example site is up on github, feel free to peruse it if you need a more comprehensive view of the working parts.

$ git clone git://

Final Thoughts and Takeaways

  • My background is in server-side software development and therefore the client-side space and its attendant technologies are relatively new to me. Before I experimented with Sass, I took it for granted that styling presentation via CSS was categorically a different process than developing software. But Sass directly counters my assumption. And even though I no longer directly write CSS when coding with Sass, its DSL makes me feel right at home when describing my presentational styles. Most importantly, Sass gives me the ability to bring my software engineering practices to bear in the presentational realm. I can’t help but think this is a big deal.

    However, I will say getting comfortable with “programmatic” CSS took a bit of mental re-orientation. I was used to having all my style definitions right in front of me, explicit and clear. Yet Sass, especially when coupled with Compass, introduces to the CSS space welcomed notions of abtraction, like modularity and encapsulation. As such, things are no longer directly in front of me. Rather, I have to approach coding CSS with the mindset of using libraries. So i have to fire up the docs (in this case the 960 plug-in Sass code), see what resources the library provides, and then determine the best use of those resources. Again, I go through this process daily when writing application code, but it felt a little awkward when first incorporating this practice in the CSS space. But once I began approaching coding my presentation layer like any other programming task, things immediately fell into place. Also, because the end product of the Sass work cycle is CSS, I had ready access to those files if I wanted want to see what was being sent to the client. And since I use Firebug as my main debugging tool, my approach to debugging the presentation layer didn’t have to change at all. 

  • I think that for small personal and professional projects Sass and Compass will help streamline CSS development. The ability to modularize and re-use code is a big win in terms of best practices and efficiency. It can also help maintain consistency throughout the code base. I think the tool would even be useful in large-scale organizations where the developers share similar values and engineering practices, and whom are disciplined enough to learn and use the Sass/Compass libraries.

    I’m perhaps a bit more skeptical about the promise of Compass to distribute reusable CSS plug-ins throughout larger engineering ecosystems. While there are surely commonplace CSS problems, I think the idiosyncratic nature of website design will at some point outweigh the ability for large scale CSS reuse. But, I do hope I am wrong on this point, as I feel Compass’s aims and values are admirable. Time will tell.

  • There is one big concern I have with respect to using Compass to maintain semantics, and it concerns optimization. The Sass ‘mixin’ model basically inlines style attributes (from, for example, 960) into your own custom CSS. The (potential) downside of this is lots of duplicated CSS rules in Sass’s generated end product. How might this model impact the file size of my custom CSS? And how to weigh this increase in file size against the benefits Sass and Compass bring to the development side of things? Are we sacrificing consumer performance for producer best practices? I don’t have an answer to this question. If anyone out there can speak to this issue, I’d love to hear your thoughts.

    If I have time, I would like to implement The Obscurantist with only the 960 framework, sans Compass, and compare the resulting CSS. I’ll just have to stomach presentation class names in my markup for the sake of enlightenment.

  • Given the programmatic nature of Sass, the Compass port of the 960 framework is extremely customizable. In effect,you get an API to generate a grid of N columns, each separated by a configurable gutter, that all together span 960 pixels. For example, let’s say you want to create a layout that is 960 px wide and comprises 5 columns separated by 10 pixel gutters. It’s pretty easy:
    @import 960/grid.sass
    !ninesixty_gutter_width = 10px

    I encourage you to dig into the 960 plug-in’s Sass files to see what other things you can tweak.

  • More generally, there seems to be a growing number of Compass modules available. Some modules come installed with Compass, while others are available as plug-ins. Therefore, you can pick and choose from various CSS frameworks as the need arises. Say you love 960’s approach to grid layouts but you prefer Blueprint’s typographic standards. Well, Compass allows you to selectively incorporate mixins from both frameworks. And since you don’t have to rely on the frameworks’ class definitions you remain in full control of your semantics.
  • And finally, a few words about the 960 CSS framework. I’ll be honest, when all was said and done, I thought – “All this for some width and margin definitions? I could have come up with that on my own with not much effort. It all seems pretty simple.” But part of me thinks such a reaction reflects, perhaps ironically, rather well on a framework. 960 does one thing-it helps you execute a grid layout rapidly, easily, and with little preparation. It doesn’t get in your way and simply optimizes and enhances your work-flow. And while it makes grid layouts seem intuitive and transparent, I’m quite sure there are subtleties hidden away that I’m not taking into account with my cursory ascription of, “That seems pretty simple.” So I’m perfectly happy leveraging the hard work of people who have spent more time focusing on grid layouts and spending my time concentrating on other aspects of my project.

    Also, and perhaps most importantly for me, the 960 framework sports the following tagline: “Sketch, Design, Code.” As I hope this article has demonstrated, I was able to utilize 960’s resources starting with the brainstorming phase (via sketchseets), during the design phase (via grid templates), and finally throughout the implementation phase (via the grid template background images and the Compass plug-in). In short, 960 provides helpful resources that can, and I would argue should, be used from project inception to project end.

In summary, if you want to leverage CSS frameworks while maintaining the semantic purity of your markup, take a moment to check out Compass. I think you’ll find it opens up a great new space of possibility.



  Comments: 9

  1. Chris Eppstein

    While it is certainly our goal to bring many of the facilities of programming to the stylesheet world, I think it’s incorrect to call Sass “code”. It is an alternate syntax for writing stylesheets and it has a lightweight scripting facility.

    Regarding the bloat that comes from prevalent use of mixins, I can tell you that if you use gzip compression, there’s almost no difference in file size of the compressed files. Also, it’s quite likely that a future version of sass will contain an optimization step that combines styles and selectors where possible. Lastly, it’s certainly possible to hand optimize your stylesheets using some of the lower-level mixins like +grid-unit-base if you want to.

    Despite the few reports to the contrary, I can tell you that Sass scales to large sites very well. I know because I run one (6.7k lines of sass, in 61 files). It is the use of abstraction and encapsulation that makes maintaining these stylesheets easier — not harder.

    Great post! Thanks for spreading the word.

  2. So you trade un-semantic HTML for convoluted CSS. Can one really argue that one is better than the other, considering that a HTML page without a CSS file is, well… just text?

  3. @Chris:

    Thanks for the reply. I hear your point about the heavyweight ascription of “code” to Sass. My goal was to show how Sass enables one to employ “coding” best practices, whether they be culled from scripting practices or more robust traditional software engineering practices. Sass is definitely lightweight and straightforward to pick up.


    Thanks for the comment. My main point in the article was to show how you didn’t have to sacrifice the semantics of your HTML to use CSS frameworks. Also, as I tried to show, I don’t think Sass produces convoluted CSS at all. I think the DSL does a great job of providing a variation on CSS that will allow anyone familiar with the latter to easily transition to Sass. True, you might have to deal with a few abstractions, but for me that doesn’t necessarily equate to convolution. Further, it’s up to the developer to decide if he or she wants to leverage Sass’s scripting capabilities. Likely, if he or she isn’t interested in building modularized, reusable Sass libraries, the Sass files won’t look much different than regular CSS files. In the end I proved to myself that there is no sacrifice necessary, one can maintain his or her semantic HTML and gain access to, I would argue, more expressive CSS via Sass.

    I do feel strongly that semantic (X)HTML is a benefit to the web community. The purpose of a document is to describe the structure of meaningful data. Semantically viable markup reaps benefits in areas like web standards, accessibility, and SEO. There is no real reason the markup should be cluttered with presentational concerns. I would argue that it is the conflation of semantics and presentation that is convoluted, rather than vice versa. I’m not entirely sure what you mean by “just text”, if you can explain further I could more readily address your question.

    To reiterate my view, HTML should be meaningful and independent of any presentational context. It’s exactly this separation of concerns that gives designers the power to employ CSS and craft myriad final presentations of the markup on varied client platforms.

  4. great work, a long awaited solution!
    thanks a lot!

  5. Marty Thornley

    I like the idea of the grid systems but have avoided them for the ugly grid_12 type names that we are stuck with. I love the idea of a mix or somehow transforming the ugly into semantic, but for someone who has no clue about Ruby, or any of the command jargon you need to use, I don’t see it being much of a solution. I’m sure it works for someone with more of a programming background, but just adds another level of confusion for me.

    I like where it’s going though. What I could see working is some kind of intermediary where I could somehow easily type in ‘.content = .container_12′ and then I could just use class=”content” or ‘.menu = .grid_4′ and so on. Does that make sense? Seems like those would be easy enough strings to parse with a simple script.

    But would any of this save any time over just renaming them ourselves in the CSS, simply doing a text replace with more semantic names?

  6. Aaron,

    Thanks so much for creating this post. Like you I have been attracted to grid based css frameworks, but have been extremely reticent to add the purely presentational markup to my (x)html pages.

    I’m going to grab your example and adapt it to my current layout project, as soon as I get home tonight.

    @Marty – what you’re suggesting “just renaming them ourselves in the CSS, simply doing a text replace with more semantic names?” won’t work cleanly. Consider the case where two semantic elements in your code use .grid_4 layout — say a callout box, and an ad container — you don’t want to give them the same class name, because you don’t want to permanantly constrain them to be the same size, however, in the current layout they are the same size. Using your suggested text replace plan, there’s no solution other than to use some ‘presentational’ name. Might as well leave it as ‘grid_4’ in that case.

    What Aaron’s method does is leave you with

    .callout {
    /* your custom styles */
    /* grid_4 styles */

    .ad-container {
    /* your custom styles */
    /* grid_4 styles */

    What non-programmers such as yourself would probably use is a simple ‘include’ syntax, like this:

    .callout {
    /* your custom styles */
    @filter-include(framework-name, grid_4);

    .ad-container {
    /* your custom styles */
    @filter-include(framework-name, grid_4);

    Run the file through a filter to transform your input css into a final merged css.

  7. FYI, I got an error trying to install the bleeding edge version of haml (2.0.9 worked, but is incompatible with compass). The error was:

    (in /private/var/root/haml)
    dyld: NSLinkModule() error
    dyld: Symbol not found: _RARRAY_LEN
    Referenced from: /opt/local/lib/ruby/gems/1.8/gems/ruby-prof-0.7.3/lib/ruby_prof.bundle
    Expected in: flat namespace

    Trace/BPT trap

    My hackish fix was to uninstall ruby-prof and then re-run the ‘rake install’. Just posting here in case anyone runs into a similar problem

  8. Hi, nice tutorial — but I don’t even know how to get my setup running. Got apache with virtual hosts running local, installed ruby, installed haml. The verification of sass says so I don’t know what to do. I’m trying ruby for the very first time. I don’t know where to start. Do I have to build a ruby app in one of the vhosts to use compass? I googled for hours but couldn’t find a beginners tutorial, step ba step, for a virtual “project”. Phrases like “path/to/your/app” really confuse me because I don’t understand what I have to do. What app? I thought I could use ruby localy, just like a shell script. That is the way I tried the first ruby “hello world” script. Can any one help me? I want to write a “compass for dummies” tutorial, but I feel like I’m completely lost, after all these hours of reading and experimenting. I did HTML and CSS by hand and suddenly found compass. After all it is not so trivial as I thought :o) If any one can help me, I’m very willing to write everything down in a tutorial, even edit the wiki. Thanks everyone. — And ruby got me curious!

  9. Thanks for your report, it has enlighten me about this framework.

Your feedback