I recently got back from CSS Dev Conf where I gave a presentation about migrating our site to Object-Oriented CSS. The project wasn’t easy and the outcome isn’t perfect but despite all of the challenges we faced, I came away convinced that it was the right thing to do.
Many of the talks I saw at the conference also included clear indications that the ideas behind OOCSS were pervading the sites and organizations represented there. It wasn’t always mentioned by name and at least as often it was other similar approaches like SMACSS or BEM that were touted but the idea of modularizing CSS was definitely a common theme.
One of the most interesting aspects of the conference was that almost all of the presenters were there because their presentation pitch has been voted in by the attendees. That means that the talks given were representative of what members of the community wanted to hear about and not just what the conference organizers decided. Developers are asking for better ways of structuring, developing, and maintaining CSS and these modular CSS approaches seem to be a welcome answer.
Despite this, there are people in the industry who have expressed concerns about the OOCSS approach. I was specifically asked for my opinion about this article by Ben Darlow: Cargo Cult CSS. I think he does a great job of capturing common criticisms about OOCSS and so I wanted to offer a response to this particular article because it would serve as a broader answer to concerns that have been expressed elsewhere.
One of the most common objections raised about OOCSS is that it forces us to use classes which are not semantic.
To me, this point hinges on an equivocation. When people refer to semantics in web development, it is almost always shorthand for content semantics. We were trained to value content semantics over all else and this has formed the basis of our best practises for years. Based on that narrow definition of semantics, OOCSS does suggest that we use non-semantic class names. But this fails to consider that “semantics” simply refers to conveying meaning. It is only associated with content because we’ve made it that way.
The way I explain OOCSS is that it is about embracing visual semantics. CSS is a language used to express layout and design and basing it on content semantic class names is actually conflating two different things. We sacrifice scalability in our CSS if we force it to be tied to a vocabulary that represents a different set of concepts.
Allowing for the concept of visual semantics does not replace the concept of content semantics. They are both valid and important. We should strive to convey as much meaning as possible in all of our code. In some cases we have tailor-made mechanisms such as HTML tags for content semantics, data attributes for data semantics, or ARIA attributes for behavioural semantics. In other cases we have fewer options to express meaning. Because the class attribute is so flexible and not definitively tied to a specific meaning, I don’t see any reason not to make as much use of it as possible. Microformats use classes to convey content meaning that can’t be expressed any other way. OOCSS uses classes to convey visual information. These are not mutually exclusive.
To me, performance is the least compelling aspect of OOCSS. Nicole Sullivan has argued for the performance benefits, but in the projects that I’ve worked on in the last few years we’ve had far bigger performance issues to deal with than small improvements in file size or repaint speed. If you are focused on the just the performance benefit of OOCSS (or lack thereof), you may be overlooking the more important benefits like clarity, reusability, and maintainability.
You Can Still Do It Wrong
Getting OOCSS right is not easy, especially because it is so unfamiliar. Don’t make the mistake of dismissing the technique based on bad examples or slippery slope arguments. Darlow offers this warning:
<span class=”display-block blue-box font-arial color-blue solid-blue-border padding-20">Party like it’s 1999!</span>
<span class=”display-block blue-box font-arial color-blue solid-blue-border padding-20">Hey, have you checked K10K.net lately?</span>
<span class=”display-block blue-box font-arial color-blue solid-blue-border padding-20">Wassuuuuuuup!</span>
“This might seem like an extreme example, but it’s the logical conclusion of a CSS framework methodology that abandons semantic class names and selectors in the pursuit of ‘modularisation’.”
I have never written any code like this and anyone that does has failed to understand OOCSS. To suggest that this is the “logical conclusion” of the approach says more about the author’s grasp of the concepts than it does about the concepts themselves.
Writing OOCSS is much more like programming than we’re used to in our style sheets and comes with some of the same challenges. Getting naming and granularity right are some of the most challenging aspects of object-oriented programming and object-oriented CSS but I’ve never seen the former dismissed because of it. Moving from table-based layouts to CSS was just as challenging and we made plenty of mistakes early in the process. The fact that it is difficult and that we can find poor examples doesn’t negate the underlying principles, it just points to how new and different this approach is.
Sticking With What Works
We’ve been building web sites with our current set of standards for about a decade now and some see this as evidence that OOCSS is unnecessary. Darlow puts it like this:
“Front-end developers have been quietly and successfully building large-scale web projects without the use of a CSS framework methodology for years. The fact that such projects have managed to avoid the use of OOCSS, BEM and others demonstrates that there are other effective ways of working.”
The counter-argument is that ours is an ever-changing field and tools and techniques will always be evolving. It’s part of what we signed up for entering this field and it is one of the most appealing parts to a lot of developers. In fact, Darlow himself perhaps puts it best when he says in the same article:
“You’re a professional web developer. You don’t write in Notepad any more, so don’t restrict yourself from using the best tools to do your job. … Read up and see how it’s being done elsewhere; broaden your knowledge.”
In that quotation, he is making the exact opposite argument for recent innovations like CSS preprocessors. To suggest that we should stick solely with what has worked historically in some cases but broaden our knowledge in others doesn’t really make sense. We should always be looking for ways to improve our work and not dismiss new ideas simply because we’ve been able to manage without them.
The suggestion made by some OOCSS proponents that you avoid using IDs gets a lot of attention. I don’t see this being nearly as controversial as it has been made out to be. For one thing, this advice is sometimes misrepresented as being about avoiding IDs for everything when it actually only refers to avoiding IDs for CSS selectors. IDs are still perfectly valid for use with forms, for in-page anchoring, for JS hooks, etc… They just become problematic within the principles and practices of OOCSS.
It’s also important to understand that this recommendation follows the rest of the instructions about how to write OOCSS. I would never tell a front-end developer to stop using IDs without providing the context of how to write CSS without relying on them. Within the framework of OOCSS, this idea becomes practically trivial. I haven’t written a selector that relied on an ID in years not because I fear them or don’t understand them but because I don’t want or need them.
OOCSS is not Perfect
While I will gladly use and defend OOCSS, I will also acknowledge that it has limitations.
The biggest weakness of OOCSS is a direct side-effect of its greatest strength. By fixing the meaning of our classes to refer to predefined visual patterns, the only way to change how a particular element looks on our page is to change the classes applied to it. That means that we’re actually editing HTML to make design changes.
While this may just be unusual in some cases, it can cause real problems in others where we may not have as much control over our markup as we do our CSS. For my project, we ran head-first into this issue because we were working with a CMS that, unsurprisingly, templated our markup. In our case, though, we wanted to be able to apply different themes to a page depending on what part of our organization was providing the content. Before OOCSS this would have been easy. I could apply a different style sheet that used similar selectors (based on content semantic classes) to style the page however I want. Now, though, I can’t change the design without changing the markup and I can’t change the markup without changing the CMS template.
In our case, we solved this by employing Sass and its @extend directive. This is actually where Darlow and I agree. CSS preprocessors are very useful tools and make modularising your code much easier. We differ, though, in how that relates to OOCSS. While he would argue that this makes it unnecessary, I would say that they are complementary (as does Nicole Sullivan).
Find What Works
I’m an advocate for OOCSS (and other similar modular CSS approaches) but try not to be dogmatic about it. Finding solutions to tough problems is basically a developer’s job description so we should have as many tools in our toolbox as possible. There may be valid reasons why this approach isn’t the best option in your situation. Just be sure you’re making that evaluation based on a compete understanding of what OOCSS is (and isn’t), and not misconceptions.