Thinking CSS First

One thing that's very nice about HAML is that when you write your code, you're thinking "CSS-first" - meaning that you don't write HTML tags (normally) - you work with classes or element ids.

I, for one, love this approach. It helps me to "mock out" a layout and then add the CSS to suit. For instance - let's say I'm putting together a page with an article, subject line, author line, etc:

article

#article-title Title #author-name Rob Conery #article-body Lorem ipsum dolor sit amet ...

This gets parsed and transalated intoTitle

Rob Conery

Lorem ipsum dolor sit amet ...

The thing I really love about this - I didn't need to think in terms of HTML angle-brackets. I like that - I like it in the same way that I don't like to think about SQL statements per se. I need to be aware of it all - in other words I absolutely need to know how the machinery underneath this abstraction works. But I certainly don't want to code in it all the time.

I think that's an important point: I really suck at writing HTML, let alone formatting it so it's readable. A lot of people don't care if HTML is readable - but you quickly begin to care when you pick up someone else's work who has no aesthetic sense (like ME) and you try to change the HTML around.

HTML needs to be maintained and loved just like code that we write - this is one reason I really, really like HAML.

Refactoring Made Simple

One thing that just drives me nuts is when I need to go into a layout and tweak it so that there are 3 columns instead of 2, or if I need to move a chunk of HTML from one area to another. I never seem to pick up all the end tags I need (because I suck at writing HTML ... ) and I invariably have to hunt down the stray div tag.

HAML makes this pretty simple. The core premise of HAML is based on CSS selectors coupled with whitespacing (like Python). That's what the inventor of the language was after - basically "let's write less, and pay attention to CSS".

If you didn't notice from the code above - HAML pays attention to the whitespace and considers anything indented under another element to be contained within it. So indenting #article-title underneath #article means that it gets wrapped inside the #article div tag. If you don't indent - the tag is automatically closed for you, on the same line.

Let's refactor the code above to wrap article in a larger structure, and also turn non-structural stuff into classes:

main

.article .article-title Title .author-name Rob Conery .article-body Lorem ipsum dolor sit amet ...

right-column

.ad This is an ad .ad This is another ad

To refactor this I needed to:*Add #main and #right-column

*Indent the article stuff under main so it gets wrapped

*Change the pound signs to "."##Too Many Divs?

Some folks feel like it's all too simple to fall into "div-itis" - which sounds a little snarky to me but if you care about using HTML for what it's intended for - then they have a good point. In the code sample I use here - it's all divs. That's ignoring the core HTML tags that are supposed to be used for these things - stuff like headers and paragraphs!

Let's tweak our code again to use "better" HTML:

main

.article %h1.article-title Title %h3.author-name Rob Conery %p.article-body Lorem ipsum dolor sit amet ...

right-column

%p.quote This is a quote %p.quote This is another quote

In HAML you can use any tag you like - just use the "%" and the letters of the tag and you're off. The same rules still apply for using classes - just add a "." - the same way you'd write the CSS.

For those of you who like your HTML 5 - we can do that as well:

%header Some Heading %nav Links

main

%article %h1.article-title Title %h3.author-name Rob Conery %section.article-body Lorem ipsum dolor sit amet ... %aside %p.quote This is a quote %p.quote This is another quote %footer Copyright ...

This would translate into

Some Heading

Links...

Title

Rob Conery

Lorem ipsum dolor sit amet ...

This is an quote

This is another quote

Copyright ...

I'm not an HTML5 or CSS expert - my goal here isn't to say "this is how HTML5 and CSS are done" - it's to show you how you can work with it using HAML.

What About Codez?

Code is pretty straightforward using HAML: if you want to output something, use an "=", if you want to process something, use a "-". If I want to loop over some articles, I could add a loop in here:

%header Some Heading %nav Links

main

  • @articles.each do |a| %article %h1.article-title= a.title %h3.author-name= a.author %section.article-body = a.body %aside %p.quote This is a quote %p.quote This is another quote %footer Copyright ...

That's Ruby code - but substitute C# in there and you get the idea, it's just one line and follows the same "indent/wrap" rules as the HTML. If you want something processed inside the loop, just indent it.

What About .NET?

HAML is huge in the Ruby world - a favorite among many Rubyists. Geoffrey Grosenbach has

probably the best explanation of HAML I have read:>When I’m designing visually in the browser, I’m thinking primarily about blocks of text and images, and how they will be styled. I don’t want to be thinking about HTML boilerplate or need to hunt to find a matching end tag.

Haml decreases the mental distance between HTML and CSS. I work directly with CSS selectors no matter what file I happen to be in.

Part of the reason Ruby folks love HAML so much is that the engine fits seemlessly into their workflow - relatively speaking. Rails and Sinatra support it straightaway - you just have to have the gem installed and then use the ".haml" file extension.

Visual Studio has a tougher time of it. I've used

the nHAML view engine a few times before, but found that each new release kept breaking old code. The plugin I was using tended to break Visual Studio as well - but I think they might have that sorted by now.

If you are interested in HAML and were thinking it would be fun to contribute to an Open Source project - nHAML might be worth your time. It's a wonderful ViewEngine - highly addicting as well. I find that going back to working in HTML (using erb or WebFormsViewEngine) is fairly imposing and noisy.

Drawbacks

Again, it's worth saying that I don't like working directly with HTML - and that's because I'm not very good at it and I lack a bit of discipline. I know that there are plenty of people out there who love HTML passionately - and if you're one of these people, HAML probably isn't a good fit for you.

In addition, if you have a dedicated HTML/CSS wonk on your project - they probably won't want to work with HAML so there again it might not be a good fit.

Working with HAML takes a bit of getting used to. The indentation rules can be frustrating at times - and copy/pasting code into an IDE can blow up the indentation and the page will throw. It takes some time and effort to know how the whitespacing works - not a lot - but just enough to notice.

Summary

Ultimately it's what works for you - right tool/right job etc. There's that angle, but I think there's something more to consider as well - does the tool you're using (in this case your view engine) nudge you to work a bit better? A bit cleaner while at the same time thinking about elegant visual design?

If so - that's great. Or maybe you have a lot more discipline then I do. Either way - I hope you found this post helpful.