OOCSS and HTML semantics

If you deal with CSS at all, I urge you to watch the video of Nicole Sullivan’s presentation at Webstock this year (and follow along with the slides on Slideshare). It’s only half an hour long, and it is an eye-opening summary of the problem of massive, sprawling CSS.

One of the core principles of progressive enhancement as a technique for web development is the separation of content (HTML), presentation (CSS), and behaviour (JavaScript). The CSS Zen Garden is the canonical shining example of how CSS can be used to completely transform the appearance of an HTML document, without having to make any changes to the underlying HTML. The problem is, this is an unrealistic example.

In the real world, we have to deal with documents and designs that change from month to month. If you are laying down a one-off site, then your CSS can be as weird and sprawling as you like, but many of us don’t have that luxury. Our CSS has to be comprehensible to our colleagues, our successors, and ourselves in 12 months’ time. It has to be structured and meaningful, and you shouldn’t have to understand all of it, or use a debugger (web inspector/Firebug) just to make a simple change.

The principle of separation of content and presentation says nothing about how to keep your CSS organized in a highly fluid environment. Just because the ground rules of CSS are easy to understand, doesn’t mean that it is easy to work with in the large. When it comes to modularity and re-use, CSS as a language doesn’t even have variables, for goodness’ sake.

My own take on this, a few years ago, was to advocate a highly modular way of writing CSS, where each “content block” (a header, a sidebar list, a blog entry) uses a completely isolated set of CSS rules. By isolating each content block, you don’t have to go hunting all over the place to find the style rules that apply to the block you’re working with, and you know that any changes you make won’t impact the rest of the site.

But as Nicole points out in her presentation, this is exactly what leads to massive CSS code bloat, and sites that declare font-size:12px 700 times. In general, more code means more bugs. On the web, more CSS code means increased download times. And although JavaScript is more often the performance killer for a typical web page, complex CSS can have a significant impact on page render times, and poorly considered CSS changes triggered by JavaScript can trigger expensive reflows.

It has taken me a while to understand the lessons Nicole has been teaching, but I now generally prefer the object-oriented style of writing CSS, although I don’t always use the full OOCSS framework itself. (I’m also not mad about the “object-oriented” name, because I think it gives the wrong impression. It is defintely about objects, but “object-oriented” has too much other baggage. I often find it easier to explain the concept as “inside-out” thinking instead of “outside-in”.)

One of the hardest hurdles to leap in coming to like OOCSS was the somewhat heretical notion of adding “non-semantic” container elements and apparently “presentational” classnames to my HTML. What finally reversed my discomfort was the realization that “semantic HTML” is not just one thing. There are, in fact, many different layers of semantics that go into HTML, and in fact belong in there:

  • Structural semantics are represented by the core HTML elements that define the document outline: headings, paragraphs, lists, tables. HTML5 adds articles, sections, figures, and other sexy stuff. To be honest, these new structural semantics have always been my favourite part of HTML5, because they make it more flexible to represent old-fashioned documents, and make it more likely that what we humans write now will be readable and comprehensible in the really long term.
  • Ontological semantics are layers of domain-specific meaning that add information about what a piece of structural markup is in the world beyond the document outline. A <section> might represent someone’s contact information, an event, or a menu of options. Microformats and ARIA roles are just a couple of widely used examples that happen to be standardized. No doubt you have come across many other examples of site-specific semantic classes, like <section class="account"> or <ul class="orders">.
  • Visual semantics represent the intent but not the implementation of the visual hierarchy of a document. This is the difference between <div class="rounded"> and <div style="border-radius:5px">. Or, to take a concrete example from the OOCSS framework, why it’s okay to do something like <h2 class="h3">. What you are saying with that piece of markup is that structurally, this header is at the second level of the document outline, but visually it should be less important — perhaps because the section in which it appears is located in a sidebar rather than in the main body.

Just because you use visual semantics does not mean you have to abandon ontological semantics. The two complement each other very nicely. But favouring visual semantics for styling (ideally derived from a style guide) means you can minimize your CSS by writing one-off rules like this:

h3, .h3 {
    font-size: 146.5%;
    font-weight: normal;
    font-style: normal;
    color: #DF2B72;

instead of repeating yourself in location-dependent styles like this

#order h3 {
    font-size: 146.5%;
    color: #DF2B72;
#sidebar .upsell h2 {
    font-size: 146.5%;
    color: #DF2B72;

The really hard part about doing it this way is finding the right balance, the right level of granularity in how your objects are made up of other, smaller objects. This is not an exact science, and there are no canonically right answers. What feels like the right level of granularity to me, might feel freakishly over-specific to you. What we can probably agree on, though, is that if you end up specifying a classname for every property + value combination on each element, you’ve gone too far:

<p class="color-red size-xl margin-20 padding-10
background-white weight-bold bg-img-monkey bg-pos-topleft">

Have a look at Nicole’s two articles about granularity and the media object for an illustrated example of how to think about HTML+CSS object composition.

Finally, I’ll bring out one of my favourite quotes: “There are only two hard things in Computer Science: cache invalidation and naming things.” Object composition is all about naming things; this makes it hard. But not impossible, and certainly very worthwhile once you get the hang of it.


5 Replies to “OOCSS and HTML semantics”

  1. Glad you liked it! It has taken me a long time to just get to the point where I understand what OOCSS is trying to do. It’s not just another CSS framework — it’s a completely different way of looking at the page. I’m happy if I can help other people see the same thing.

Comments are closed.