Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Why we don’t use OOCSS (but we should)

Charles Hansen
Saturday, May 25, 2013

I recently had the opportunity to pair with Nicole Sullivan (of OOCSS fame) for a few days on my current project.  I learned as much as I could about css components in the three days available and then rebuilt the most painful part of our UI with components over the next week.  I learned two broad things from this experience.  First, css components are amazing.  I didn’t realize how much pain I had in css until I saw how much easier it was with components.  We should definitely use them.  Second, css components feel weird in the normal web development world.  There are good reasons we haven’t used them at Pivotal.  It just turns out the reasons for not using them aren’t good enough.

I may write another post on why OOCSS is so amazing, but I think the more interesting post are the reasons to resist OOCSS.  Hopefully someone just trying it out will be pre-warned about these pain points and will be able to make a smoother transition.

1.  HTML and CSS are just not as important as the server code or javascript for a web developer.  I spend most of my time in ruby or javascript and am always looking for ways to make coding those things more sustainable.  I don’t spend very much time in HTML or CSS, so there isn’t the same drive to improve them.  I need big wins in CSS coding to justify changing anything.  Luckily, OOCSS fits the bill.

2.  You can’t test css.  Agile development relies heavily on the ability to refactor, which relies heavily on test coverage.  Say you had a page with many buttons, but the client only tells you about a new one every week.  With each new button, you add some html and css, and then some javascript click handlers.  After enough buttons, you refactor the javascript to reflect your new understanding of the page.  You can do this safely with enough test coverage, but how do you refactor the html/css without breaking something?  A style guide goes a long way here, but it’s not the same as test coverage.  In my refactor, I just had to spend the time comparing the look of the refactored css with old versions.  Mildly painful, but still worth it.

3.  The design patterns of rails are simply different than OOCSS.  If I want a page with a list of users, I will make a users_controller.rb with an index method.  I will make a user_list.js file for client interaction (assuming it is complicated enough to need one).  I also want to make a user_list.css file. Unfortunately, almost anything I would put in the user_list.css file is bad for OOCSS.  I need a lists css file which doesn’t know anything about users.  In fact, none of my css files should know anything about users if I can avoid it.  This isn’t hard to do once you realize it is important, but it never occurred to me until Nicole pointed it out.

4.  Javasript class names are usually semantic.  OOCSS class names are not.  They should not depend on the content in them, and might have absolutely nothing to do with the underlying business logic  If I have a list of users in my page, I naturally want to make a ul with a class like “user_list”.  In OOCSS most of the list styling for a user list should come from some generic class like ‘list_vertical’.  You don’t want the ‘user_list’ class unless the javascript needs it.  This felt unnatural for a few days, but I eventually got used to it.

5.  There is a lot of extra HTML in the early stages of an OOCSS refactor.  I ended up creating extra uls and divs in the weirdest spots just to get things to layout correctly.  And then there are all the extra classes.  You aren’t supposed to re-use javascript selectors in css, so you need to write new selectors for that.  You also shouldn’t use parent classes in your selector, so html that used to look like

html:
<div class="error">  
    Something went wrong!
    <button>Try again</button>
</div>

css:
.error { background-color: red; }
.error button { color: white; }
now needs to look like

<div class="error"> 
    Something went wrong!
    <button class=button_error">Try again</button>
</div>

.error {background-color: red;}
.button_error {color: white;}

You still need the “error” class to style the error div so the “button_error” class is just thrown on top.  The whole situation is made worse by html that is full of copy-paste.  In my refactor, there was a particular button type that was created over 100 times in our html and I wanted to add an OOCSS class to it.  We pulled it into a partial to solve the problem, but too much of this and it starts to feel like we need to refactor our html templating before we can refactor OOCSS.  I’ve been assured that a full OOCSS refactor actually results in 20-50% less html depending on the project.  The ‘extra html’ phase is only when you have added the OOCSS html but haven’t added enough that you can remove your old html scaffolding.  Even during this phase, the extra html isn’t so bad because at least you have a lot less css.

6.  Components only work if you see patterns in layout that repeat themselves.  Many of the components I am now using weren’t obvious to me as patterns worth extracting.  I didn’t start seeing them in the site until I became familiar with the common OOCSS components.  You do actually have to put effort into this.  The other failure mode here is if your website just doesn’t have repeatable patterns due to inconsistent design.  Now you need to add convincing your client to streamline the design to your list of tasks.  On the plus side, making css components is a very good way to show your client the inconsistencies in the design and should result in a better site.

None of the difficulties listed above are deal-breakers, but they do add up to a lot of headwinds in moving to OOCSS.  Even with those headwinds, the transition has already been an easy win for my current project and I believe most sites would find the same thing.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Launching Focused Jasmine Specs From RubyMine

Charles Hansen
Wednesday, May 8, 2013

RubyMine is great for launching focused rspec tests, but is a little trickier for launching Jasmine specs, but we have had it working on my current project using a shell script and RubyMine external tools .  The script relies on using sed to parse the first line of your spec file, so this actually only runs the describe block at the top of your file.  The steps for our setup below.

  • Create a shell script somewhere in your project:
  • Go to RubyMine -> Preferences -> External Tools -> +
  • This should launch a new tool dialog.  Fill in name, descriptions, etc
  • For program, you should link the script you just created.
  • For parameters, you should use “$FilePath$”
  • Bind this external tool under keymaps (look for the name you just gave it).  We use command-option-control-f8
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 11/29/12: Time.now, more like Time.at(2011)

Charles Hansen
Thursday, November 29, 2012

Helps

mock object nil when it shouldn’t be

(rdb:1) @registration

RSpec::Mocks::Mock:0x3fda7eabfd68 @name=”mocked registration”

(rdb:1) @registration.present?
false
(rdb:1) @registration.nil?
false

  • mock objects don’t always define nil? or present?

Interestings

David Chelimsky handing off rspec

David Chelmisky is stepping down as the RSpec lead after 6+ years. http://blog.davidchelimsky.net/2012/11/28/myron-marston-and-andy-lindeman-are-rspecs-new-project-leads/

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 11/28/12: Mohawk Day!

Charles Hansen
Wednesday, November 28, 2012

Helps

Request log output in controller specs

We are getting info level log out put when running our specs from the controller examples. I don’t know how they are getting turned on nor how to turn them off

  • Crickets

default host when using url helpers in regular classes

How do most projects handle the default host for url helpers when the helper is being included in presentation classes etc?

  • Pass your controller to your presenter and ask the controller for url helpers

making rspec2 custom example groups

any one know how to define custom example groups in rspec and associate them with specs in a given folder.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 11/26/12

Charles Hansen
Monday, November 26, 2012

Interestings

dotenv Gem

Have you tried this gem? It kind of rocks it. Works great with a Heroku development environment. It even has files for different Rails modes, e.g. .env.test

https://github.com/bkeepers/dotenv

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Hunting Memory Leaks in Backbone

Charles Hansen
Tuesday, October 23, 2012

Ever notice your backbone app slows down considerably after using it for a few minutes? Or maybe your event callbacks are called more than once each time the event fires? Or my favorite, Chrome runs out of memory if you have a few tabs open that have run your entire Jasmine suite? This means you have backbone leaks.

I just spent the last week hunting these down in a very large app. It turns out the problem is tractable with a few guidelines. None of this is ground-breaking, but I wanted to put it all in one place.

1) The object retaining tree in the Chrome heap profiler is amazing. Use it.

2) Restrict use of views in closures, or as contexts to callbacks in event bindings. This is explained in much more detail here. I’ve also personally found nothing but trouble with _.bind for similar reasons.

More specifically, never use model.bind or model.on in a view without keeping track of that binding and remembering to unbind it when you want to tear down the view. This is the motivation for coccyx

3) ParentViews with childViews need to keep track of their children. When you tear down the parent view, you also tear down the child views. Before implementing this step, the object retaining tree for my zombie views was shockingly large. Afterwards, it was a manageable ~4 retainers for the zombies.

Parents keeping track of their children seems simple enough, but it is easy to lose track of the little devils.

For example:

ParentView = Backbone.View.extend({
    render: {
        //render the rest of the view first

        this.collection.each(function(model){
            var childView = new ChildView({model: model});
            this.$("ul").append(childView.render().$el);
        });
    }
});

loses any reference to the child views, and they will almost certainly leak (assuming the child views bind events to their models that need to be cleaned up).

Using the principles names from coccyx, the same code needed to be rewritten as

ParentView = Backbone.View.extend({
    render: {
        //render the rest of the view first

        this.tearDownRegisteredSubviews();

        this.collection.each(function(model){
            var childView = new ChildView({model: model});
            this.$("ul").append(liView.render().$el);

            this.registerSubView(childView);

        });
    }
});

where tearDownRegisteredSubviews calls tearDown on any registered subviews. This way, the only child views still in memory are those initialized in the most recent call to render. Those remaining views should be torn down when the parent is torn down.

View.tearDown itself can be a bit sticky because you still have to worry about event bindings from global objects and other difficult-to-clean sources, but those solutions are more project-specific.

Hope that points you in the right direction.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 10/26/2011: Nothing

Charles Hansen
Wednesday, October 26, 2011

Nothing today

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 10/24/2011: Women who code meetup

Charles Hansen
Monday, October 24, 2011

Interesting Things

There will be a Women Who Code meetup on Tuesday. Sarah Mei will be giving a lightning talk at it about a day in the life of an engineer. The organization is for both women who are currently coders and those just interested in coding.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Charles Hansen

Charles Hansen
San Francisco

Subscribe to Charles's Feed

Author Topics

jasmine (1)
rubymine (1)
agile (5)
backbone (1)
javascript (1)
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >