Last night, while work on a very cool client project for Blue Flavor, I took a short break to make the following tweet: “It’s amazing what you can do in very little code when you apply object-oriented principles to CSS. Wish more front-end devs understood OOP.”
I got a surprising number of responses from people asking what I meant, exactly, and for examples. I also got several responses, and a few IMs, from people touting Compass and Sass, a pair of Ruby projects that provide useful language features and syntax to CSS and CSS frameworks, allowing you to do all sorts of fancy things.
The OOP concepts I was specifically referring too are mostly around inheritance, co-reuse, and the Don’t Repeat Yourself (DRY) principle. Think subclassing, mix-ins, etc. Clearly, CSS doesn’t provide this kind of syntactic sugar, and it’s very debatable whether it should or not. The W3 is strongly against even adding variables (or constants) to CSS. I personally am in favor of variables in CSS, but would be against adding much logic to the language. So it becomes a question of where to draw the line, and I strongly suspect the slippery slope is why Bert Bos is so vehemently opposed to variables.
So while CSS doesn’t offer real subclassing or mix-ins, it does allow for something that can (sort-of) replicate that functionality: multiple classes per element. For example, I can make a class of
.box that defines some basic layout structure, and another class of
.rounded that provides rounded corners, and classes of
.narrow that define some widths, and then easily create boxes of varying widths and styles by assigning multiple classes to an element, without having to duplicate code in my CSS.
Of course, there are two big issues with this that are causing the Andy Clarke’s and Jeremy Keith’s of the world to throw up in their mouth a little bit as they read this: so-called “classits”, as well as so-called “non-semantic” class names. So allow me to address each…
“Classitis” is a popular terms for using too many classes. The first time I was warned against class over-use was way back when Zeldman first released Designing With Web Standards, and at the time, it made good sense to me. However, having learned about object-oriented programming over the past few years (through Python and Django), I’m not sure I still agree. If I have 100 “boxes” on a page, and 75 of them use rounded corners, and 20 of them are wide and 80 are narrow, I basically have two choices.
First, I can create a bunch of classes. For simplicity, let’s call them
.box-rounded-wide, and so forth. You can see that several of these would be required to cover all the possible box styles. And what’s worse, each of them includes a lot of duplicate code. They all need the basic box structure. Several of them need the rounded corners. And so forth.
The other option, as I said above, is to use multiple class names on an element. So, you end up with
<div class="box rounded wide">. The advantage here is around maintainability: in your CSS, you no longer have to repeat the code for the base box structure over and over again, which means when you change it, you only have to change it in one place. And I think we can all agree that the extra code that it takes us to use three class names is far less than the extra code it takes us to redefine a box three times in CSS. So I say get over your fear of multiple classes. Having five classes on one element is nothing to be ashamed of.
So on to those presentational class names: first, it’s worth noting that I’m only using them here because a box with rounded corners at varying widths is simple for us all to understand. These concepts certainly apply whether it’s called
.navigation. Second, I would (and have, several times in the past), question exactly what the reasons are for avoiding presentational class names. While I do advocate being as semantic as possible, it’s important to note that presentational class names cause no real-world problems of note. So, I’m all for being semantic, right up to the point where doing so is disallowing me to stay DRY, making me less efficient, and bloating the hell out of my code. That having been said, I’d never actually use a class name like
.box-rounded-wide, and I hope you wouldn’t, either. It just makes for a good example. Bottom line: the only thing you really gain from using 100% semantic class names all the time is that Jeremy or Andy get a little tickle in their loins when they view your source. If that’s important to you, then by all means, be semantic.
Okay, so what about Compass, Sass, and similar projects? Before I tell you why I don’t think they’ll work in a lot of cases, let me be clear: these things are very cool. I’m very impressed by Sass, especially. It’s powerful as hell, offering elegant language features to CSS. No doubt using Sass produces cleaner results than using just piling on the class names, like I’m suggesting.
But the one big looming problem with these projects is this: they’re for programmers. Sass may seem pretty simple to you, but I guarantee you it would confuse the hell out of most of my co-workers — and my co-workers are all fucking brilliant designers and front-end developers. The problem is simply that most designers and CSS authors aren’t programmers. What’s more, most of them don’t want to be programmers. As soon as you start talking about mix-ins, subclassing, and passing arguments, their eyes roll into the back of their head. Applying multiple classes to an element, though? That, they can understand.
So, what was the impetus for my tweet? Basically, I meant not being afraid of multiple classes, even if they’re borderline presentational, and thinking of CSS classes as objects that can extend one another (even though they technically can’t). However, this is really only the tip of the iceberg as far as applying OOP concepts to CSS. Nicole Sullivan recently did a talk on Object Oriented CSS and touches on many other aspects, almost all of which make perfect sense to me. It’s a great place to start for more info on this sort of thing. If you don’t have some basic understanding of OOP concepts, the benefits of this stuff may still be lost on you a bit. That’s fine. You’ll come around. :)
For the record: I joke with puritans Jeremy and Andy because they’re friends and I know they can take a little ribbing. I love both those guys — nothing personal intended!
Update: My rounded box examples were shit. I should have taken the time to come up with some good, non-presentational examples, to avoid the semantic/non-semantic part of this post all together. Matthew Anderson posted a comment below in which he provided much, much better examples: “Messaging in applications is a great example. Your success, informational and error messages should have a similar look and feel. Using classes like “success message”, “info message” and “error message” are no less descriptive and no less communicative than “success-message”, “info-message” and “error-message”. However, they are a lot more maintainable and you accomplished it with less code.” Perfect!