OOCSS + SASS = Fewer Classes On Your Elements

update 3/29/2009 8:23 AM: Turns out Chris Eppstein is way ahead of me. Check out Compass. It’s a project that delivers your favorite CSS frameworks as SASS mix-ins. Oh and also it integrated with your favorite Ruby web development framework.

Stubbornella you have captivated me. I am now watching Nicole Sullivan‘s Object Oriented CSS talk for the second time. The OOCSS framework is a terse but ambitious thing in the tradition of YUI Grids CSS and Blueprint but with opinions that reach beyond grids, resets and typography.

While I have certainly not mastered the OOCSS concepts I do have some early observations I’d like to share nevertheless. This of course is dangerous territory since I risk having to eat my words later. So be it. Feel free to feed ’em to me as appropriate…

It strikes me from looking at the UML diagram for OOCSS that something is missing, or more accurately, some things are being conflated which shouldn’t be. If we’re thinking about objects and classes here the first question should be: what are we modeling? Well the semantic HTML folks might say we need to model things like paragraphs and headings, or at another level contacts and phone numbers, or at another level sidebars and navigation. These are all semantics.

When we think about modeling these things in HTML in such as way that CSS can be profitably applied, we use HTML element types to directly model semantics where we can (p element for paragraph, h1 element for top-level heading) and we use class attributes to express the rest (‘top-nav’, ‘address’, ‘phone’). If you have a look at the OOCSS UML diagram you will see in the “page layout” section a set of classes that fall into the former category ( ‘doc’, ‘hd’ for header, ‘bd’ for body, ‘ft’ for footer).

So far so good. But now how do we actually extend a class? The approach suggested in OOCSS is to change the (HTML) markup. One example from the talk is to specialize the media block class ‘media’ so that the fixed-size media is on the right instead of on the left. The suggestion is to define a new class ‘media_ext’ along with a new set of CSS rules. Then the idea is to change our HTML so that the element of interest carries two classes: ‘media’ and ‘media_ext’. And then we define some CSS for the new media_ext module, something like this:

.media_ext .fixedMedia { float:right }

This is the fundamental approach in OOCSS, so fundamental that it is on the short list of 10 Best Practices from slide 19 of the talk:

9. Extend objects by applying multiple classes to an element

The library defines a small set of base classes and a few core extensions to those. Users are invited to extend these further and we change our HTML to carry the full set of classes expressing semantics, layout and skinning too, all as separate classes.

The value in this approach is it certainly brings order to chaos. The downside is twofold: first we must pollute our HTML with layout and skinning choices and second, we must rely solely on coding conventions to ensure that each HTML element carries a self-consistent and complete set of classes.

aside: To me this feels much more akin to structured programming or maybe at best “abstract data types” than it does OO. I don’t really see language-level inheritance here, nor do I see polymorphism. But that’s just a terminological nit.

The first problem we need to solve is to get rid of the superfluous classes (on our elements). How could we make a media block (“fixed-width media object on the left with an open editable zone on the right”) into a right-handed media block without changing our HTML? Well the classic way in CSS is to use context to distinguish this situation. So let’s imagine that every odd media block ought to be right-handed. A classic approach is to have an ‘odd’ class on the element (or to use nth-child pseudo class). Perhaps something like this:

.media.odd .fixedMedia { float:right }

Where target is the fixed-width object we’d like to be on the right-hand side instead of the left. You get the idea. The problem with this approach is that we’ve just coded up some potentially reusable stuff (the {float:right} part) and we’ve got no way to reuse it in other circumstances. Also we are now guilty of committing pitfall #1 from the talk:

1. Location dependent styles

So you can see that we are definitely violating a key tennet of OOCSS. If you’re already an OOCSS dogmatist you may want to stop reading now. Still with me? OK, what if we want a right-hand media block for even rows next time? We’d have to edit that last CSS rule to look something like this:

.media.even .fixedMedia { float:right }

Yuck. What’s going on here? The problem is that CSS has no named/reusable/callable construct. No macro. No function. No Class. OOCSS does the best it can with plain old CSS by requiring us to define a new HTML class name. That lets us define a reusable set of CSS rules for it, but at the cost of polluting our HTML at each use.

I think a good way out of this is to break out of plain old CSS into a higher realm. Both SASS and CSS-SSC have a macro concept. SASS has its mixins and CSS-SSC has its base and based-on. What these actually add to CSS is named abstractions and reuse. So I could define a SASS mixin like this:

=right-hand-media
  .fixedMedia
    float: right

Now that is a reusable module. In my application I can apply that module to an element:

.media.odd
  +right-hand-media

Yay. Now I have the best of both worlds. If we have another app that wants even media items to be right-handed then we just define this:

.media.even
  +right-hand-media

The value of this is that I didn’t have to change my HTML markup in order to change the layout. There are examples of using the same approach to define a clearfix module. To those who say this approach is going to generate a lot of CSS I say, “well maybe, but I think our first priority needs to be making our source code manageable and this approach may just help us do that.”

As I already pointed out, this proposal (using SASS mix-ins or CSS-SSC macros to implement reusable modules, and then using contextual CSS Rules to apply those modules) violates a core principle of OOCSS. On the upside it solves one of the wish list items from the talk (on slide 60):

1. Extending objects—possible to make “sale module” inherit from “module”

.module{}
.saleModule{extends: module}

Now that approach is a bit different from the one I described for right-hand-media. But it is clear that mix-ins or macros could easily be used to reuse .module in .saleModule right? SASS mix-ins, for instance can be used (as in my first example) as straight-up mix-ins, or to implement inheritance. The choice is yours.

To close, I highly recommend watching the Stubbornella’s presentation. Twice. There is just a ton of gold in there. Meanwhile, I’ll go experiment with SASS mix-ins and let you know how it works in practice and how it can be combined with some of the other principles highlighted in the talk.

About these ads
This entry was posted in CSS, Ruby, tool. Bookmark the permalink.

12 Responses to OOCSS + SASS = Fewer Classes On Your Elements

  1. 7kittens says:

    Looks like a lot of css in markup to me. No thanks.

  2. Semantics and OOCSS will never mix. OOCSS definitely has some great advantages and I already apply some of these concepts already to extend classes.

    ex: .sidebar { … } .sidebar.left { float: left; }

    But as you can see from my example here, I am mixing two conflicting concepts. Semantics say i should define all my styles related to sidebar WITHIN sidebar, but OOCSS says i should make my classes extend by using multiple classes.

    So where’s the middle ground? A little bit of everything. Too much OOCSS and you’ll quickly be infected with classitis.. too much semantics and you’ll quickly have 30k of styles.

    In my opinion, put semantics FIRST and keep it flexible with extended classes especially with floating and widths.

  3. Sam says:

    Whilst I really like some of the concepts introduced by OOCSS, I shared your reservations about using so many classes in the markup. We’re currently using the Compass interpretation of Blueprint on a new project and I find it extremely helpful – although the initial learning curve can be difficult, as the extra layers of abstraction means you have to approach debugging somewhat differently.

  4. bburcham says:

    I like Blueprint a lot Sam. As for Compass, I’ve been leaning away from it (yet another language). Instead I’m using good old ERB templates to gain dynamism in my stylesheets. See Dynamic CSS Goop.

  5. Pingback: OOCSS: Reutilizando al máximo los CSS @ hdennison.com : Blog profesional de Harold Dennison

  6. Lance Otis says:

    Extend a class? The approach suggested in OOCSS is to change the (HTML) markup.
    The downside: changing every html page every time you want to extend the class differently. ???

  7. hugh says:

    Perhaps it’s no coincidence that semantic and pedantic rhyme. Yes, it is a good idea to name classes where possible in a way that describes their content and role. But semantic markup is surely trumped by efficient CSS… A little more markup can mean much, much less CSS.

    Faster development time and faster download times are prizes that are worth having at the expense of pedantic markup and if somebody says it’s not semantic, I think the correct response is to shrug the shoulders.

  8. Dale Sande says:

    Semantic CSS and OOCSS, dogmatically, will never live together in harmony. It is clearly one or the other. Following the OOCSS model you will quickly start creating a library of non-semantic css ‘widgets’ that you apply to your markup.

    Being a preacher of building a project styleguide, I was OOCSS before OOCSS was a thing. But now becoming a more experienced Ruby developer, I am coming to the same conclusions as you are with the coupling of OOCSS and SASS. In fact, I can’t see any other way of doing it.

    A great example. I am working on a project where I have aside bubbles for additional information. Going with OOCSS I would need to have a class of something like “more_information” appended to both to cover the simular UI cases. Then to adjust for the delta between the two, I then would add the class of ‘call_to_action’ and ‘white_papers’.

    But using SASS, I can simply use the single semantic class and then using the similar UI as a mixin within SASS, I can reuse that style without copying and pasting.

    So in essence, I guess what we are saying here is in principal the same thing, build re-useable elements within your CSS and have a way to easily re-use that code.

    I guess you could say, OOSASS?

  9. How about reversing the diagram? Instead of having subclasses “inheriting” the base class, having the base class “willing” the styles to the subclass?

    For example, instead of this CSS and HTML:
    .media { … }
    .comment { … }

    Have this?:
    .media, .comment, .menuitem { … }
    .comment { … }

  10. Stupid WordPress stripping my HTML.

    I wanted the first one to have:
    <div class=”media comment”>…</div>
    <div class=”media”>…</div>

    And the second to have:
    <div class=”comment”>…</div>
    <div class=”menuItem”>…</div>

  11. Hi. Somehow I’ve missed all the OOCSS story, so I developed a parallel philosophy – for my project. My way is simular to OOCSS, but not exactly. I also divide structure from elements (to be able to position blocks on pages independly). The thing is, that I use “namespaces” – they are just a chain of class names in BODY, representing navigational path, just to be able to speak to the .element_x on one page different, than to the same .element_x on the other page. I pack namespaces into variables and use in SASS like that:

    in my _variables.sass partial I write:
    $picturesTemplate: “.bigproject.our_products.product_x.product_x_pictures”

    in my partial _picturesHeader.sass, that describes this particular element:
    body
    &#{$picturesTemplate}
    .element_x

    Doing so you can have both “library” for typical .element_x styles as well as be able to write alteration easily. If I have to differenciate between many nearly–the-same elements on one page (what is very rarely), I can alway simply put one more level to the selector and use descending selection. Or, if the elements are too different, just handle them as different elements and give them different names.

    Sorry for the grammar – English is not my strength :)

  12. Pingback: Why I chose Sass « An Innovatory Life

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s