In a previous post, I said:
Shoehorning CSS and HTML into PHP abstractions prevents the code from being DRY and ultimately leads to code bloat, because, the CSS and HTML require a far more granular object structure than the PHP.
And then I didn’t expand on it, or give proper context. Ooops, sorry!
Correct granularity is one of the keys to tiny CSS
In the PHP layer, the following stream story (from facebook) might be a single object. All of the logic of determining which bits of HTML to show or hide are contained within one object structure.
Frequently, developers try to make the CSS match this middle-end logic. We expect all the CSS code for the stream story to be sand-boxed within a wrapper id, for example #story. This ends up with bloated code that isn’t DRY. Why? because the proper architecture for the CSS layer is much more granular. Trying to base the CSS architecture on the PHP layer is something akin to trying to use the DB schema to configure apache. It just doesn’t work.
So we can see that the stream story example above is composed of many more granular objects. As we make the objects more granular, we begin to see the same patterns emerge over and over, and the same objects become much more reusable. We start to see that most sites on the interwebs are composed of the same basic repeating patterns combined in different ways. As a side benefit, the CSS gets *much* smaller and simpler.
The stream story, one PHP object, is composed of several HTML & CSS objects:
1 heading
5 Media Blocks
2 Link Styles
1 Comments List
1 Action List
1 Paragraph
Benefits of this approach?
Getting the CSS object granularity right means that our CSS (and by extension, our HTML) become much simpler and lighter. Our little reusable object can be employed across the site to create new and different pages without adding to the weight of the CSS.
As a starting point, I recommend creating the following objects: headings, lists, text treatments and links, containers, media, grids, and template. Create all your smallest objects first, before you build whole pages, and your CSS will stay small by default.
Comments
16 responses to “How to create CSS objects? Get the granularity right!”
Hey Nicole,
Good post, and good point. I think the 11-ish html/css objects you broke it into feel right, but I’m curious what the markup and css selectors might look like for that example? What’s your latest thinking on applying/binding those repeating css and/or html constructs?
By the way – just stumbled across your blog again. Would be good to catch up sometime.
Hi Nate!
Nice to hear from you, yes, let’s grab coffee sometime!
While you were commenting, I was actually writing a blog post with the HTML and CSS of the media object. It isn’t quite done though, and I have to go to bed because Velocity Conference starts tomorrow. 🙂 I hope I can get back to it soon.
Thanks for following up on this!
So, to rephrase and understand, you’re saying that elements should be styled independently of where they’re used:
Some of us might style the “img.avatar + paragraph” layout as as something belonging to “ul.comments” (and even going so far as to sandbox both within the outer “#story”): Not reusable.
The other part is realizing that packing all the style rules for an element into one selector might not be the right approach: mixing all of color, layout, typography, etc. into one style makes it less granular, and less composable.
Therefore, instead of trying to style a specific case, the goal is to realize that e.g. the “.media” layout component of that comments list is a pattern — separate from what style rule defines its background color, and independent of the comments list that contains it.
Yes, I think I get it: granularity over modularity.
You’re right that this results in shorter CSS, but it also means more markup in the HTML, right? It seems like you would have to mark up more specific elements with more classes, instead of leaving it up to a parent selector and heavier CSS.
It also seems to imply using more “visual” than “semantic” classes to describe elements. (Where “.comments” is something we’d call purely semantic, and “.greybox” purely visual…) Actually, I don’t think “visual” is even the right word for the kind of markup that this promotes. The OOCSS way is really neither of these — “object-oriented” is probably the right description!
@Andrew Vit You are getting it now. 😉 It is still modular, the pieces are just smaller than we’ve been building them.
You might think the markup would get larger, but in practice, Facebook saw a 50% reduction in HTML size when Stefan Parker implemented a bunch of this into their home page stream.
You definitely don’t want to have presentation based classes. There is nothing worse than a class “bigRedHeading” that actually makes text blue. You want your choice of classes to represent the visual semantics of the page (I alluded to this in my previous post). Those visual objects and patterns are what I am defining in an object oriented stylesheet.
So instead of:
#stories .story .comments .comment {}
you would have .comment {}
However, if a comment in a different context is different then you need to clarify the context:
#stories .comment {}
#somethingElse .comment {}
or
.storyComment {}
.somethingElseComment {}
etc?
@adam, I would do it like this:
.comment {}
.specialComment {}
Where a special comment would extend the comment, assuming they shared enough common styles, so the HTML would be:
[…] reading here: Stubbornella » Blog Archive » How to create CSS objects? Get the … This entry was posted on Tuesday, June 22nd, 2010 at 7:41 am and is filed under Uncategorized. […]
Nicole, thank you for the clarification!
At my current gig, we’ve decided to ignore IE6 and it’s been spectacular. I’ve been able to experiment with an approach that I could never hope to put into production before. But I’ve been running into difficulties. For instance, what I’d want to do with the HTML in the above comment is this:
and then style them with these selectors
.comment { property: value }
.comment.special { property: value }
What it’s created is a special type of class that can be used for nothing but inflecting. Inflection as in verb inflection, such as -ed in English to designate past tense. By doing this, one can never apply styles to .special, or if one does, one runs the risk of unpredictable inheritance. I could provide more detail, but I don’t want to do it in a comment.
What’s been your experience with compound selectors?
Nicole — all I have to say is that I love the way you think. Great stuff, and great explanation. One thing I’d love to see is an example where you convert some overly large rules to something leaner and more object oriented CSS-ish.
Do you recommend design guides(html page created to show how css classes are used) still using OOCSS, and would it become easier with OOCSS? It seems like it would.
Great writeup! Please do more of these where you work through examples! I’m on my third gig where I’ve used it, and I still get stuck on how to compose objects. You’ve lit a lightbulb for me again…
This seems trivial, but I’m curious: How would you handle the line at the bottom of the story (begins with twitter icon, contains padlock image and ends with @stubbornella) — two media blocks in a grid? or one media block with an image in the middle of the text? Two blocks seems like markup overkill but better reuse of objects…
@Mike I’m not sure I know what you mean, can you show me a screenshot & URL?
Ok, the in-depth write-up on the media object is published: http://www.stubbornella.org/content/2010/06/25/the-media-object-saves-hundreds-of-lines-of-code/
This has been great, you guys ask questions, that I then use as the topic of the next post. 😀
Thanks for your help!
When I create a top-level class like this I find it helpful to UPPERCASE the name to avoid conflicts. So I can use .comment wherever I want, but if I run across .COMMENT, I know it’s a sitewide element and has CSS already defined for it.
Hi there,
I wonder if you saw the comment and question from Jesse. Any thoughts or experience with that approach in regards to performance, wins or fails.
Best,
Michael
I don’t use compound selectors. They aren’t necessary.