- Code Samples
Original Article: http://blog.carbonfive.com/2009/03/html/compass-960-semantics
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://github.com/nex3/haml.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/ the_obscurantist/config.rb the_obscurantist/src the_obscurantist/src/grid.sass the_obscurantist/src/text.sass the_obscurantist/stylesheets the_obscurantist/stylesheets/grid.css the_obscurantist/stylesheets/text.css
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
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:
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:
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... */ #container +grid-container +clearfix .title +grid(12,12) .publication-info +grid(12,12) .volume +grid(2,12) +alpha .date +grid(8,12) .number +grid(2,12) +omega #article +grid(12,12) .body +grid(7,12) +alpha .captioned-photo +grid(5,12) +omega #sidebar +grid(12,12) img +grid(5,12) +alpha .body +grid(7,12) +omega #tagline +grid(12,12)
- ‘+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://github.com/aaronsbrown/obscurantist.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 #container +grid-container #main-content +grid(4,5) #nav +grid(1,5)
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.