Object Oriented CSS, Grids on Github

How do you scale CSS for millions of visitors or thousands of pages? Object Oriented CSS allows you to write fast, maintainable, standards-based front end code. It adds much needed predictability to CSS so that even beginners can participate in writing beautiful websites.

I recently presented Object Oriented CSS for high performance web applications and sites at Web Directions North 2009. If you didn’t attend my talk, you are probably asking yourself “what in the world is OO-CSS?”

Object Oriented CSS: Two main principles

1. Separate structure and skin
2. Separate container and content

I’m writing a framework to demonstrate the technique, but more than anything, Object Oriented CSS is a different way of approaching CSS and the cascade. It draws on traditional software engineering concepts like extending objects, modularity, and predictability. Solutions are judged based on their complexity, in other words, “what happens to the size of the CSS file as more pages and modules are added?”

The answer, for most sites, is that it grows out of control and becomes an unmaintainable tangle of spaghetti code. People often complain about CSS, and rightly so — even though it inspired a rant, I understand their frustration.

Current methods for writing CSS require expert level ability just to get started. To become a CSS expert, you need to spend couple years coding away in your basement by yourself before you are remotely useful. Front-end engineering needs to accomodate entry level, mid level, and architect level developers, but our sites are too brittle. You may have a perfectly accessible or high performance website, and then the first newbie to touch it, ruins it. Our code should be robust enough that newbies can contribute while maintaining the standards we’ve set.

We don’t trust each others code

Imagine a JavaScript developer wrote a function to return area, and every now and then it randomly returned the diameter instead. The function would never make it through a code review, and yet we tolerate the same thing from CSS, as if it were immune from normal programming best-practices. This is why CSS code reuse is almost nonexistent. An object should behave predictably no matter where you place it on the page, which is why Object Oriented CSS avoids location dependent styles.

What not to do

#myModule h2{...}
#myModule span{...}
#myModule #saleModule{...}
#myOtherModule h3{...}
#myOtherModule span{...}

Developers have tried to sandbox their CSS into individual modules, to protect against the cascade. But in doing so we’ve ended up with a mess.

Object Oriented CSS Grids on github

My Object Oriented CSS grids and templates are open sourced on github. They have all the functionality of YUI grids plus some important features.

  • Only 4kb, half the size of YUI grids. (I was totally happy when I checked the final size!)
  • They allow infinite nesting and stacking.
  • The only change required to use any of the objects is to place it in the HTML, there are no changes to other places in the DOM and no location dependent styling. Eases back-end development and makes it a lot easier to manage for newbies.
  • Solution for sub-pixel rounding errors.

http://wiki.github.com/stubbornella/oocss

Check out template.css and grids.css and the docs on the github wiki.

My prediction is that you’ll be writing complex layouts in less than 24 hours without adding a line to the CSS file.

What’s up next?

Template and grids are ready for rock and roll. Please be my alpha testers, put them through their paces. Let me know if you find bugs or want additional functionality. I’m also hoping to contribute some of this back to YUI since they now have a github repository. How cool is that?

Rounded Corner Boxes and Tabs

Next up, modules. There are a million cool ways to create rounded corner boxes. I’m going to take several of my favorites (like CSS Mojo and Arnaud Gueras blocks) and convert them to OO-CSS. This will make it super easy for newbies to create their own modules, without needing to understand the minutiae of browser differences.

Video / Podcasts

YDN will publish a video of my talk and Web Directions North is putting out podcasts. I’ll tweet and post when that happens. The audio contains a lot more detail than the slides, so check it out as they become available.

107 thoughts on “Object Oriented CSS, Grids on Github”

  1. This looks looks very interesting! But are there files missing in the github download? I could not find the template.html or library.html that you mentioned..

  2. Hi Nicole,

    I ran across your presentation and enjoyed it. You’ve got some really good ideas in there that I’ve been using for a while, based on experience and intuition. I think it’s great that you thought out and enumerated them, especially limiting classed tag selectors, and applying multiple classes.

    I would like to ask your opinion on something relating to avoiding IDs to style main content areas. Because of the potential for newbies to ruin the site (as you put it), I’ve been taking an even more pessimistic approach and using IDs, mostly using them as a way to limit in-experienced developers of small page components from inadvertently altering the styles of main content areas.

    The people I work with have CSS ability that tends to trend more towards the low end. Additionally, I know I am creating more maintenance points in the code, but since the overall site doesn’t have a uniform CSS framework, and their components may reside multiple places, that’s a necessary evil (for now). I wonder what you think about this, would you still recommend your avoid IDs statement in this case? Do you have any experience in a situation like I describe? I would love to try your way, as I believe it is better, but I am wary of the result.

    Thanks, and thanks for your contribution to our discipline!

    Eddie

  3. Hi Eddie,

    You are taking the route a lot of people take now, which is to sandbox modules as much as possible. It is a better solution than CSS entropy, and it will be easier for you to transition to OO-CSS. I don’t use IDs to style anything inside the main content areas. They can be used for linking purposes or JS hooks, but styling based on an ID automatically means that you can never use that style twice in one page. Object reuse makes them performance “freebies”, and we like that a lot!

    As the architect, you should write the structure object; set up how the rounded corner box is created, positions all the presentational elems for corners or other features, and deals with browser differences. Newbies write the skins for these modules (borders, colors, background images, etc).

    I built large scale sites (1000s of pages, millions of visitors) using the OO-CSS method. It scales well and, when done correctly, it means that the individual components a newbie would be working on are relatively predictable. Code review is easy because there are clear rules about acceptable ways to extend objects. This kind of feedback makes new developers productive really quickly.

    I managed a team of front end developers at FullSIX (a web marketing agency) in France who are among the most talented people I’ve ever worked with. At some point our success meant that we had far more work than we could handle. It is very hard to hire front-end experts (there is no school for this stuff!), so I started an internal internship program where designers who were interested in exploring code (but had little to no previous experience) could come work as junior members of our team for one month.

    * Week 1: They learned about semantics and built html from existing CSS. Learning to build new pages without writing more CSS, HTML syntax, multiple classes, validation, semantics, intro to code review, etc.
    * Week 2: They built simple content objects (headings, lists, etc) for a week. Learning CSS syntax, how to extend objects, colors, % sizes for text, etc.
    * Week 3: they were building block skins. Borders, colors, background images, basic positioning, sprites. They worked with an amazing senior developer who answered a ton of questions and really helped them scale the learning curve. He also happens to be a very talented code reviewer.
    * Week 4: they were productive members of my team building skins that were production ready.

    Their code is live on a client website. It is as good as anything written by the senior developers, maybe better because they didn’t have to un-learn bad habits. :)

    Cheers,

    Nicole

  4. Hi! I’ve been trying your framework (although not in a real project, just playing around with it a little bit) and really loved it. After playing with the grids for a while i thought of adding some rounded corners, and found a method i really liked. I’m sure you’ve seen this, but just in case, check the author’s explanation in http://virtuelvis.com/gallery/css/rounded/

    What i liked about this method is that there is no need to add any markup to get the effect. The downside is that it doesn’t work in IE because it uses :before, :after and content, but maybe it’s a place to start. All i needed to change in the html was adding a rounded class. I would like to know what you think about this.

    Thanks!

    Ariel

  5. Excellent stuff, Nicole. Thanks for publishing it.

    We’ve approached our HTML by putting main content first. This has done well for SEO, although I have no stats to show. Would you comment on why doing that is or is not a concern?

    Our headers, footers, and extra columns all follow the main content in our HTML.

  6. @Jim I debated this a lot. Early sites I worked on had a more normal template structure with an uber class on the body that showed or hid left and right columns based on the template. Users of the custom CMS got really frustrated when they would build a page in a three column layout, realize it needed to be two columns and find they had to start from scratch because there were multiple templates / starting points. You probably noticed that main is a liquid column, it expands to take all the room left over after the left and right columns have been rendered.

    I would rather have the source order reflect visual order (because it is weird if tab order varies from that), but I sacrificed that preference because I felt it was more important to have a single template. The current code means that if you want a column, the only requirement is to put it in the HTML, no costly changes to make elsewhere in the dom.

  7. thanks for this – i think these are some truly useful building blocks in there and some good advice.

  8. Hi Nicole!

    Once again, a brilliant presentation, thanks! It’s comforting to see that there are other UI developers out there that are serious about their work. I think front end stuff is overly disregarded in many organizations. Your UML modeling approach to UI design was a good pointer, I wouldn’t have thought to use that for things other than scripts and server side design.

    I wanted to add an idea to your CSS wish list that I’ve been thinking about lately. You hear a lot about rounded borders coolness and other neat tricks in CSS3, but continuing from where you left off, I think CSS would benefit from scripting languages, such as JavaScript. I think the potential to have not only CSS variables, but calculated values and true object inheritance would make CSS so much more powerful. Consider the following:

    @reset: { margin:0; padding:0; }
    @body: { font-size: 1em; }

    h1 {
    uses: @reset;
    font-size: @body*2;
    }

    The syntax here isn’t optimal, but you get the idea.

    Furthermore, if CSS were extensible, we wouldn’t have to wait for the W3C and the browser vendors to churn out and adopt new features. That way, we could implement the “cool” effects much sooner. Don’t get me wrong, I’m eagerly waiting for these features to hit the main stream, but the point is, the standardization process and adoption progress is too slow!

    Browsers are quickly adopting lightning fast JavaScript engines, so I don’t think the performance hit of a Cascading Style Script language would make things any worse, rather the opposite actually, if you think of the bandwidth saved on CSS. I’m working on a proof of concept where a site’s CSS is completely replaced by a jQuery based JavaScript file that does the styling. Will be interesting :)

  9. Nicole, this is very interesting! I really envy those interns, because the description of the things they learned in those three weeks sounds exactly like what I am trying to do.

  10. Having worked on numerous projects that’ve become victims of CSS code bloat, I can appreciate how your wonderfully articulated development paradigm offers hope – a better way to build websites.

    I only wish I’d seen the article sooner – or had the foresight to conceive such an approach to working with CSS.

  11. Thanks Nicole,

    If you’ve coded a large evolving website with 50 developers of which 4 or 5 know CSS —this is very relevant.

    Another concept to add to the mix ( or at least another label ) would be CSS Patterns.

    Having a library of CSS patterns ( say a fieldset with a ( absolutely positioned) checkbox and a (margined) label ) can greatly reduce spaghetti CSS.

    Doug

  12. Thanks for your reply.

    You mention your preference with tab order compared to visual order yet the code on github (currently) has this order: leftCol, rightCol, main. That, I assume, is not what you mean by visual order and there is some other corner cutting here with ideals to make the basic framework example simple to implement.

    I haven’t forked (yet) but I would think addressing this in the README or wiki might be helpful.

    Since reading your post and code I’ve been wracking by brain trying to think of as simple a way (or at least close) to allow a different source order. But this has made me look back over a few current projects and I’ve cleaned some things up already.

  13. Your slideshow was 100% fluff and 100% non-informative. I waited and waited for something to draw from for my own coding purposes but all i got was a “lol, use my code” at the end. Brilliant slideshow /sarcasm.

    How is this OO again? CSS isn’t a true programming language, it has more in common with an ini or config file than it does with traditional compiled or scripting languages (C, Java, PHP, JavaScript, etc.), so why are we trying to apply terms to it that can’t even translate the same way? There is no inheriting in CSS in the same way that one inherits classes in any language that supports objects in any way. All you’re really doing is applying a bunch of additional classes to an element to give the illusion of “extending”. That’s not even remotely close to the spirit of OO.

    Your “framework” (I still feel dirty using this word to refer to anything CSS related) is just as bad as the others because it encourages poluting the HTML with names that rely on visual cues (size1of3) rather than be descriptive of the content they contain (subnav). As a result, you will have to change the source any time a redesign is done (yes, even if you are using various templates and includes). It’s a nice thought, but until I can have #subnav EXTENDS .size1of3 { … }, there’s no such thing as OO CSS. I like being able to offer alternate style sheets or use them as a way to debug or do live redesigning, hardcoded visual cues make it impossible to turn a 2-column site into a 3-column.

    Design Patterns or Libraries, yes. Frameworks or OO, no.

  14. Thanks everyone for your compliments and suggestions, very much appreciated.

    @C I’ll be speaking at Velocity Conference (o’reilly). Alternatively, I teach performance and OO-CSS bootcamp at companies that want to get their developers and designers up to speed quickly.

    @Jim – I prefer tab order to match visual order, but I also want a single template. As often happens in web development, two important goals came into conflict, and I made a judgement call about how to resolve it. In this case tab order matches visual order for everything except the right column.

    I mentioned this in the “known issues” section of the template docs on the wiki. I’ve also started to compile an OOCSS FAQ which is now growing as people ask questions.

    @DougWig Do you have a live example?

    @Glen CSS variables seems to be a popular request these days. A server-side solution that cached the resulting CSS file could probably achieve the same thing with no performance penalty.

    On a production site, I’d be wary of using JS to allow CSS3 for non-compliant browsers. Dom access is really expensive. I’m more keen on the idea of designing a fallback solution and/or using progressively enhanced PNG8. I saw a presentation by the IE8 team at Web Directions North, IE6 usage is dropping fast, I don’t want to make the site slow for IE6 users just to provide exactly the same rounded corners as good browsers get.

  15. CSS variables are a step in the right direction. If the variables could contain CSS entities (not just string values), their usage would be close to what I’m trying to get at. But yes, I agree that a server side option would be sufficient for now, but it takes away the simplicity of writing CSS in a “flat” file from a UI developer’s perspective.

    I take your word on the performance hit issue. Using JS was not my intended solution for a production site, rather a POC that CSS could benefit from having scripting capabilities. The browser needs to churn through a sites’ CSS already and decide how to render the output, so my thought was that adding a little “intelligence” to CSS wouldn’t hurt the process :)

    OO CSS… keep up the good work!

  16. hi there i just found your framework some hours ago and i started to test it, i just came up with a rather different solution to the same problem of sub-pixel rounding problems, my solution, pure javascript, i know is not the best choice at glance, and indeed, it takes time to calculate all stuff.

    so my questions, is there a way to not use overflow:hidden?
    i tried it and it breaks.

    i also tried this layout

    column

    column

    column

    column

    column

    column

    and it breaks too. did i made something wrong.

    i wish we can colaborate to find a solution

    my frameworkgithub url: http://github.com/azendal/elastic/tree/edge

    has some cool things like vertical-center, fixed-center-column, auto-columns and others, hope to get your comments.

    great work on the framework, hope to find a pure-css solution for roundings

  17. No offense, but don’t you think that the two “cornerstones” of your presentation, i.e:

    1. Separate structure and skin
    2. Separate container and content

    … are just reinventing the wheel and the hot water?

    Sorry, but all through your presentation I did not find a single useful thing that is not known to an average CSS developer. No, you are not Gottlob Frege of the web-semantics, the hot water and the wheel have been discovered long before you got into web-development.

  18. @c. As I understand it from Christian Heilmann, people learn better when they are not presented with the same information in written and spoken form simultaneously. I’d love it if CSS had a proper way to extend objects. Until then, I use multiple classes.

    @Glen true re: flat file, not sure the benefit is worth the complication, but it is something I’ve been wanting to play around with. Because ultimately, I’d like to build a skin builder, that automatically builds out basic site content. OO-CSS is easy to write, but I just think it would be fun.

    @Fernando Ooh, careful, I’m instinctively wary of JS solutions to style problems, DOM access is super costly. Yes, it is possible to write grids without overflow hidden (contexte de formattage). You need to use content after to clear lines and body, and set float right on the last Unit for all browsers. The down side is that I use the contexte de formattage to take care of subpixel rounding errors, if you remove it, there will be a couple pixels gap between the last unit and the previous sibling in Safari and Chrome, but not in Firefox. I’ll probably write a version like that for the print stylesheet because Firefox has some bizarre printing issues when faced with overflow hidden.

    @Martin – None taken. :)
    1. Separate structure from skin isn’t about HTML and CSS. Within the CSS, have one class that takes care of all of the little presentational elems, browser differences, basically all the complicated bits. Then build on that class with multiple skin classes, which then only need to contain simple things like border colors, background images, etc. The skins become super predictable.
    2. Separate container and content – a glance at the CSS of most sites will tell you no one is doing this properly. At best we manage to separate by module, or sandbox individual components. Unfortunately, each of the modules has container and content completely tied together. This makes the CSS grow over time and the site not scale or perform well.

  19. What are your thoughts on adjusting/extending gutters? Looks like they’re 20px.

    Also, what would be the best way to use this for a site designed for 1280 or, say, 1440 resolution (just a different resolution than you’ve provided and not a 100% width)? Would you just change the width in #page within template.css? Are you planning on creating wrappers for other/various fixed-width resolutions?

    Have you checked out Blueprint (http://www.blueprintcss.org/)? What do you think about that?

  20. This is one of the most original takes on CSS and frameworks that I’ve seen in a long time. I can’t comment fully as I’ve yet to make a proper investigation of your code base, but you’ve managed to articulate and answer nicely some concerns that I’ve had on my mind for some time. Most importantly effective reuse of code, and minimising growth of one’s css files.

    All the best,

    Sam

  21. Woh … Just one question. You’re using “Cascading stylesheets” and you’re trying to _get rid of_ the cascade? (Ok, maybe one more: CSS is hard to learn?)

  22. @cancel bubble – the oocss grids have no gutters. The logic behind that is that gutters belong to the elem they are on (p, list, whatever).

    If you want to be able to have full width items, you can’t have gutters by default or you will get into costly closing of the containing tag with gutters, placement of the full width item, and reopening a new containing tag with gutters. In hand written HTML this makes the code more complicated and less semantic, in a CMS environment it is treacherous or impossible.

    You can see how I set gutters on the content items in content.css. This is still a WIP as I’ve found a more or less stable solution, but I wanted more testing before releasing it properly. It does require some margin reset classes, basically by default margins (gutters) should be set well, then in rare circumstances you reset them to 0 or extra large. This bothers me semantically, but practically speaking if you don’t give people a correct way to do it they’ll put it directly inline.

    I documented how to extend an object in the faq yesterday. The example is a column, but it applies to page width as well. An example in the code of how to extend #page is .liquid. If you know you will never EVER use the 950px layout, you can of course overwrite it in the normal non-OO way with your custom width, but keep in mind that if you do that you limit your options in the future. You can do it, but you should hesitate and reflect A LOT before you do, because product managers and designers will always surprise you with their feature requests.
    http://wiki.github.com/stubbornella/oocss/faq#extend

    @Martin On github. http://github.com/stubbornella/oocss/tree/master

    @Sam Thanks, feedback is always welcome once you’ve had a chance to explore.

    @yhv Your comment made me smile (and think for a while!). I’m trying to effectively use the cascade within any one object and limit its affect on other objects. More of this will be obvious when I start releasing modules. They are more complex than grids.

    @Diego @Spike Thanks! CSS is engineering AND design. That is part of what makes it so hard.

  23. Hey,

    In the grids_docs.html, during the AG Test a few of the “lastUnit” classes have become lower-cased (line 194, 201 for example) – thought I’d let you know.

    Could you provide a link to a more complex site that you’ve developed using OO CSS? I’m keen to proposed it to my fellow developers for our e-commerce sites but I can’t come to grips with how the CSS in the download would expand to a site in this way.

    Thanks,

    Adam

  24. olá, queria saber como você escolhe nomes para os modulos, pois já faço orientado a objeto a um tempo, diferente do seu, mas lembra bastante, mas o maior problema é com os nomes, pois eu nunca sei que nome dar, pois o módulo as vezes pode ter o tanto uma lista de links para outros sites, quanto uma lista para produtos, e eles serem iguais, ou bastante similares.

    translate by google

    Hello, I know how you choose names for the modules, because I am instructed to object to a time other than his own, but remember a lot, but the biggest problem is with names, because I never know what name to give, because the module the times can be both a list of links to other sites, as a list for products, and they are equal or very similar.

  25. Hey Nicole,

    First off – respect on your ooCSS, very smart libs that you came up with!

    Trying them first time on a 100% height height sample page however I chewed a lot an what was causing that page to render body background image only for viewport height until I saw libraries.css’ “reset” rendering color and background-color for html element.

    Removing all color assignments from libraries.css and content.css would make the libs
    * smaller
    * contribute to their minimized, efficient approach
    * … and leave the above headache with me ;)

    But anyway – thanks again on these CSS, will follow up their development on Github.

    Cheers,
    Stefan

  26. hay đấy ! ….. sướng tay viết tiếng việt … thằng nào đọc được thì đọc ….=))

    Thanks !

  27. Hi Nicole,

    Great to see your work on this. My only gripe is the use of _floats and _overflow which does not validate. Have you considered moving these to a separate file and to target the browsers who need them using more valid methods?

    cheers,

    /Anton

  28. @Anton – Yup, I did think about doing that. Let me explain my reasoning. Obviously, the first consideration is keeping hacks as few and far between as possible.

    1. Adding a separate stylesheet would add an additional HTTP request and increase total file size for a browser that already struggles with performance.
    2. I like to keep all the code for any one object in one place. I think it helps minimize the number of hacks used especially as a project evolves over time.
    3. Dev tools for IE6 and earlier are extremely primitive, which makes having hacks and normal code side by side even more important. I want to be able to figure out quickly when I have an IE bug which properties are coming into play. Again, I think this helps minimize hacks.
    4. The spec indicates that properties which are not understood should be ignored by the browser. Given that the _ behavior of IE6 and earlier is very well known, I can reasonably expect that good browsers will always ignore this property.
    5. Using conditional comments means that each html page has to contain a link to the IE specific stylesheet. One day (I can’t wait!) when IE6 market share drops to the minimal levels of IE5, I will turn off this code, but the last thing I want to do is touch 100s or 1000s of HTML pages. I’d rather have only CSS dependence on CSS hacks, rather than pushing this into the HTML. Unfortunately, IMHO the end of IE6 compatibility is farther off than we would like because quirksmode behavior in IE often falls back to an IE5.5 type model.

    I think my choice helps minimize the total number of hacks, improves performance, and has little future risk. On the other hand, if seeing the _ in your code makes you feel nauseous, you can absolutely move that to a separate file.

    Cheers,
    Nicole

  29. Nicole,

    I really love some of your concepts. Your OO idea is very similar when I start to write CSS, always trying to reuse it. But I failed since I poorly organized it. I have some questions for you after checking your code.

    1. The template.css and grids.css work exactly as YUI Grids. YUI Grids 3.x even more powerful than before. Why do you re-write it? Only make the file size become smaller or have any other reasons?
    2. Why do you choose camel case instead of hyphen separated as your coding convention?
    3. Any real website use your oocss framework?
    4. Any videos provided yet? Since I think I might not get the whole picture and also really interested in the UML part.
    5. The way you use CSS is not very semantic. You used some presentational naming scheme for selectors. What is your opinion to semantic? Or that’s just the necessary evil?

    Thanks,
    Joseph

Comments are closed.