“Describing in the Browser” with OOCSS-Inspired Microclasses

View demo

Over the course of the past year, the way I approach CSS has fundamentally changed for two reasons.

The first reason is that I now use SASS. I could drone on for days about how amazing it is, but I think enough blog posts have been written on that topic. (Having said that, please note that everything I am going to discuss here is a zillion times more awesome and powerful when combined with a preprocessor like SASS or LESS.)

What I want to talk about instead is the second reason I’m writing styles and markup a lot differently than I was 12 months ago: a little toolbox of Object-Oriented CSS–inspired microclasses that allow me to code in a way I like to call “Describing in the Browser”.

Ugh. Microclass? Describing in the Browser? That sounds pretentious and, well, hard. Au contraire, mon frère. This is one of my favorite and most frequently used microclasses:

.pad-box { padding: 20px; }

Have I blown your mind yet?! No? Try this sucker on for size:

.content-box { margin: 20px 0; }

No love? OK, time to bring out the big CSS3 guns. BLAM!

.corner-box { border-radius: 4px; }
.shadow-box { box-shadow: 0 5px 5px rgba(0,0,0,0.3); }

Not exactly cutting-edge stuff, huh? In fact, if you’d told me a year ago I’d be writing a blog post advocating the CSS you just read, I’d have slapped your new iPhone 4S right out of your hands before you’d even had a chance to chat with Siri. Devoting a whole class to a single declaration? What? Why? That looks like some wack Dreamweaver-generated code from 2005 (anyone else remember style-261 {color:red}?).

And me-from-a-year-ago would have been about right: a microclass in and of itself is nothing to write home about. It’s just a tiny, generic class that does one presentational “thing”. However, it does that one thing really well, and true to the principles of OOCSS, it does it anywhere. No matter where — and to what element — you apply .pad-box, you’re going to reliably get your 20px of padding. However, the real magic of microclasses happens when you combine them. Here’s some markup I wrote today:

This is where things finally start getting cool. For one thing, I didn’t have to create any new classes to style this div: All I had to do was combine six existing microclasses to get where I wanted to go visually. (While working on Kunvay, for example, I found that it wasn’t uncommon to implement an entire page of content with a fairly complex layout, without needing to write a single line of new CSS.)

Example markup for microclass blog post

So while I’m rocking what some people call “class-itis” (a.k.a., a sh$t ton of classes) in my markup, my CSS is lighter and more maintainable – and that’s a tradeoff I’ll make any day.

Describing in the Browser

So that’s great, but what I’ve really fallen in love with (and bear with me while I get a little pretentious) is the way that microclasses allow you to “describe” the visual presentation of an element while writing markup in a way that can feel as natural as composing a sentence in your native language. Compare the visual/design requirements for the above div with the markup itself:

A rounded-corner box, filled with the client’s signature dark orange, with a little bit of padding, a drop shadow, and white text; and there’s going to be stuff before and after this content, so also add some margin to the top and bottom.

See the symmetry there? I’ve found that with a library of these small, generic classes at my disposal, writing markup has transformed from a chore into something expressive and creative: As we all know, every block-level html element is essentially a blank rectangular box; once I’ve set up my microclasses for an app, I’m able to easily and intuitively describe what I want each box on my page to look like and how I want them laid out.

DRY as a Bone

A welcome side effect of this technique is a new-found level of DRY-ness in my code. I used to do stuff like this:

Well, hmmm, it seems like most forms need a little space around them, so I’ll stick this in my main styles

form { margin: 20px 0; }

And then invariably there’ll be a situation where a form doesn’t need that space around it — usually because its container element already has some padding or margin; so I’ll have to write something like this:

.my-container form { margin: 0; }

But then, of course, the client introduces a second form within that same .my-container element, and in this case, the second form does need some space above — but not below — it. So I’d hate myself and maybe give the stupid form an ID to overwrite all the things, like this:

#username-form { margin: 20px 0 0; }

These days, I simply add my trusty .content-box and .last-box microclasses to any block-level element I want to separate out with some top-only vertical white space:

.content-box { margin: 20px 0; }
.last-box { margin-bottom: 0; }
<!-- the first form in our example above -->
<!-- the second form -->

Beyond the original microclasses, I’ve not had to write any CSS to override the element’s default styles. Instead, I simply describe right in the markup how I want each form to behave visually: content-box adds the margin we need, and .last-box erases the bottom margin.

And if, say, the client or I decide that second form’s not quite “popping” enough, I’d just do something like this:

Example form for microclass blog post

Translated into English: A form with whitespace at the top but not the bottom, with a border, rounded corners, a light gray background, a subtle bevel effect and some padding. Total lines of new CSS? Zero.

Consistency: the hobgoblin of little minds (and little classes)

Using microclasses automatically enforces a consistent look and feel because elements all pull a particular visual property from a single class. When I start a project and tweak the values for my .shadow-box class, for example, I’m making an (easily editable) decision about what I want an outset drop shadow to look like throughout the app. Likewise, when I assign a value to the margin in my .content-box class, I’m deciding how much white space should separate all the stuff (divs, forms, sections, whatever) in my app.

“But, wah!”, I hear you saying. “I don’t want to use the same outset drop shadow and margin everywhere on my site. I wanna be creative!” Well, I do, too, sometimes. To accommodate situations like these, I’ve developed a “micro > mini > [normal] > mega” convention in my microclasses. Sometimes I need the micro-, -mini and -mega classes; sometimes I don’t.

.content-box { margin: 20px 0; }
.content-box-micro { margin: 10px 0; }
.content-box-mini { margin: 10px 0; }
.content-box-mega { 30px 0; }
 
.shadow-box { box-shadow: 0 5px 5px rgba(0,0,0,0.5); }
.shadow-box-mini { box-shadow: 0 2px 2px rgba(0,0,0,0.5); }
.shadow-box-mega { box-shadow: 0 10px 10px rgba(0,0,0,0.5); }

Still not creatively satisfied? Well, IMHO if you’re using more than three varieties of outset drop shadow, you’re probably doing it wrong. Haters gonna hate.

Give it a try

I’ve prepared a demo page that uses some of my favorite microclasses. Let me know if you find them useful. As I said at the beginning of this post, adding a precompiler like SASS or LESS to the equation only makes things 100 times cooler. (These days most of my microclasses are tied to SASS variables or mixins.) For the purposes of this article, however, I wanted to keep the focus on microclasses and how using them to “describe in the browser” has helped me work faster and produce lighter, more scalable CSS..