Responsive Design Comparison: Neat vs Foundation

In the interest of improving my design skills, I wanted to brush up on a couple of different grid-based systems that provide responsive design capabilities.  There are several to choose from, but I settled on trying out thoughtbot’s neat library and Zurb’s Foundation framework.  Along the way, I also got a chance to play around with thoughtbot’s Bourbon library.

Just The Grid, Thanks

Now first off, comparing neat to Foundation is like comparing apples to fruit salad.  neat is strictly a grid system, it is not a full-blown framework, like Foundation.  There is a time and a place for either approach, but since I wanted to focus primarily on how the two grid systems work I think it is mostly a fair comparison.

I developed two bare-bones apps that just let me play around with the grid system and some basic styling.  All I really wanted to do with the apps was to have a few static pages, see how the grid system layout worked, and how it responded to different screen sizes (desktop, tablet, phone).  The apps can be found here.

These apps are a simulation for a wine store application.  Again, wasn’t going for a full functioning app.  Just wanted the following features in the demo apps

  • Page header with some simple navigation links
  • Home page with a grid-based sections for “Staff picks” and “Calendar of events”
  • Responsive design to change the layout for desktop/laptop, tablet, and phone contexts

tl;dr

Either neat or Foundation is a solid choice for a grid system.  Both default to 12-column grids, and can configured to support other layouts.  Both are really easy to integrate into a Rails application.  Both also have good documentation, though I might give Foundation a slight nod there.

As far as just the grid system, my preference would be for Foundation.  For me, the syntax of defining the grid system seemed a little more straightforward.  I also liked that when nesting, the child elements don’t need to know about the number of columns in the parent.

Going with a full framework also brings some extra functionality.  I was able to play around with the block grid, the top-bar navigation, and the easy to set up “hamburger” menu icon.  I think it has really solid documentation as well.

Now let’s get to the details…

neat

neat defaults to a 12-column grid, which I like a lot since your sections can easily switch between multiples of 3 or 4 without changing the overall number of grids.  You have the ability to configure the number of columns you want the grid to have, but I had no reason to want to do that with what I was doing.

A grid region is defines using the outer-container mix-in.  According to the neat docs, you can have multiple outer-containers on a page, however they can not be nested.  Given the simplicity of my app, I just threw it on the body element.

body {
  background-color: $background;
  color: $text;
  font-family: 'lato';
  @include outer-container;
}

The span-columns mix-in is used to specify how many columns an element should span.  If the element is nested, you must also specify the number of columns its parent element contains, for example, @include span-columns(4 of 8) specifies that the element takes up 4 columns of an 8 column parent.  I personally found having to specify the parent information to be a bit of a nuisance, and one where neat and Foundation differed.  It wasn’t a show-stopper, but I didn’t like having to concern myself with it.

Responsiveness is attained using the media mix-in.  Inside of the block for the media mix-in, you can define the features for that context.  This allows you to redefine columns, font sizes, whatever for that particular context, e.g. tablet or mobile.  This gives you a lot of control, but to me felt a little heavy. Here you can see where I define that an element normally spans 4 of 8 columns, but for the tablet and mobile contexts spans 4 of 4 columns.

.staff-pick {
  @extend .tile;
  @include span-columns(4 of 8);
  @include omega(2n);
  @include media($tablet) {
    @include span-columns(4 of 4);
    @include omega();
  }
  @include media($mobile) {
    @include span-columns(4 of 4);
    @include omega();
  }
...
}

You can also change the width for when the context switches as well as the number of columns in the grid for the context using the new-breakpoint mix-in.  For my application, I went with an 8 column tablet breakpoint and a 4 column mobile breakpoint.

$tablet: new-breakpoint(max-width 900px 8);
$mobile: new-breakpoint(max-width 600px 4);

I think one of the strengths of neat may be that you have very fine-grained control or the grid and underlying elements through the multiple mix-ins it provides, but that will also take a little more work (or familiarity on neat) on your part.  I also found it required reading both the gem docs on github and the neat page docs to fully understand how to set it up and get running.

Foundation

As I said earlier, Foundation is a full blown framework, along the same lines as Twitter Bootstrap.  You get the grid system, but also navigation elements, buttons, forms, controls of all different kinds, alerts, drop-downs, and on and on.  But for the purposes of this comparison, I wanted to concentrate primarily on the grid system.

Like neat, Foundation uses a 12-column grid, and like I said earlier, a 12-column grid has a lot of advantages.  You can also customize the number of columns in the grid system, but the default was fine for what I was doing.

Foundation uses a different format for specifying the grid layout.  Rather than try and spell it out in all it’s detail, take a look at the grid documentation.  Overall, I found the ability to specify the columns all on one line more readable than the way neat does it.

To define an element that spans 4 columns for large screens and 2 for mobile, you would do something like this

<div class="row"> 
  <div class="small-2 large-4 columns">...</div>
  ...
</div>

Whereas with neat, you would do it this way

  .some-style {
    @include span-columns(4);
    @include media($mobile) {
      @include span-columns(2);
    }
  }

Foundation also has some nice features that make layout a lot easier, IMO.  My toy app had a section for “Staff Picks” that displayed a bunch of wines in a grid layout.  With Foundation, I could use the Block Grid feature to easily lay out the grid based on the screen size.

<div class="row">
  <ul class="small-block-grid-1 medium-block-grid-1 large-block-grid-2">
    <% @reviews.each do |review| %>
       .......
    <% end %>
  </ul>
</div>

Now in 1 line, I can easily see that the block-grid will have

  • 1 review per row for a small screen
  • 1 review per row for medium screen
  • 2 reviews per row for large screen

Foundation also provides some easy mechanisms to implement a “hamburger menu” (the three vertical bars) for the navigation links when going to a small screen, using the class=”toggle-topbar menu-icon” line.

<nav class="top-bar" data-topbar>
  <ul class="title-area">
    <li class="name">
      <h1><%= link_to "Denomy's Wine Emporium", root_path %></a></h1>
    </li>
    <li class="toggle-topbar menu-icon"><a href="#"></a></li>
  </ul>
  <section class="top-bar-section">
    <ul class="right">
      <li><%= link_to 'Home', root_path %></li>
      <li><%= link_to 'About', about_path %></li>
      <li><%= link_to 'Help', help_path %></li>
    </ul>
  </section>
</nav>

Foundation also provides a lot of tools for handling nesting, offsets, incomplete rows, and other potential gotchas that really look great for helping to manage the grid.

Given that you get a lot of other features with it, like forms, alerts, drop-downs, etc, I am really starting to look forward to using Foundation more in the future.

It wasn’t all perfect, there were some annoying things.  For instance, I was unable to use a linear gradient in the header bar, but for the most part it was pretty easy to work with.

Adding In a Splash of Bourbon

I am happy to say that it was easy to use both neat and Foundation in a Rails app with Bourbon.  Bourbon has some a really rich set of SASS mixins that can be used to customize the look of your app.

Programmatically Clearing the Facebook Share Image Cache

When you share a URL on Facebook, it scrapes the page for the URL for the Open Graph data to determine what image/video to display.  Facebook caches the image for that URL, so if you change the image and then share the same URL at a later time, the old image will still get displayed, which is probably not what you want to do.

Facebook provides the Open Graph Debug Tool that can be used to manually clear the cached value for the URL, but that may not be a workable if your website allows images to be changed dynamically.  Ideally, you would want a way to programmatically clear the cache after the associated image is changed.

Fortunately, there is a way to clear the cache using the OpenGraph API by forcing a scrape of the URL. The key is to set the ‘scrape’ parameter to true in the API call. The following Ruby code assumes that the Facebook application id and secret are stored in environment variables.

facebook_open_graph.rb

module FacebookOpenGraph
  def self.clear_cache(url)
    params = {
      :client_id => ENV['FACEBOOK_APP_ID'],
      :client_secret => ENV['FACEBOOK_SECRET'],
      :grant_type => "client_credentials"
    }
    uri = URI("https://graph.facebook.com/oauth/access_token?#{params.to_query}")
    response = Net::HTTP.get(uri)
    access_token = Rack::Utils.parse_nested_query(response)["access_token"]
    unless access_token.nil?
      uri = URI('https://graph.facebook.com')
      res = Net::HTTP.post_form(uri, 'id' => "#{url}", 'scrape' => 'true',
          'access_token' => "#{access_token}", 'max' => '500')
    end
  end
end

Then to clear the cache you merely need to call the clear_cache method, passing in the URL being shared.

FacebookOpenGraph.clear_cache("http://myurl.com/some_cool_page")

Aikido, Controller Tests, and LinkedIn at Launch Academy

I had a nice visit the other day speaking at Launch Academy.  It’s no secret that I am a big fan of the program.  As a community, we need to do more to produce good entry-level developers and also to help them develop their careers.

My talk was geared towards preparing them for what happens when they leave Launch Academy and some of the things they can do to continue learning and growing as software developers.  The three topics: Aikido, Controller Tests, and LinkedIn don’t seem to have anything to do with one another, but let’s look a little closer.

Aikido

I don’t know the first thing about aikido, but I do know of a talk that Alistair Cockburn gave where he talks about aikido and the three stage of learning: Shu, Ha, and Ri.  These stages of learning are common to almost any endeavor, including software engineering.  Right now, the students at Launch Academy are in the shu phase, learning a single technique from their masters.

When they go out into the world, they will be exposed to new techniques and new masters, and it is their responsibility to be open to these new techniques, try them out, and incorporate them into their own practices.  This is the ha phase.

With some hard work, practice, and luck they may reach the ri phase, where they are inventing their own techniques, but that wasn’t part of my talk.

I highly recommend the talk by Alistair Cockburn, it covers so many great ideas about developing your craft.  He is an amazing guy and his talks are always engaging.

Controller Tests

I have been thinking a lot lately about controller tests in Rails.  What value do they serve, are they still worth writing?  This is probably the subject of another blog post or series of posts, but in the talk I wanted to tie it in with the concept of shu-ha-ri and being open to new ideas.

When I first started learning Rails, one of my primary resources was Michael Hartl’s amazing tutorial.  So many of us owe him so much for showing us the way into an awesome framework.  At the time I was learning, I recall the tutorial having a fair number of controller tests, and those tests became part of my shu learning phase of Rails.

As I started to develop more Rails apps, and getting exposed to more practices and techniques, I was forced to rethink the role of controller tests.  I found some of the ways I was using them had little intrinsic value.  In some cases, they were essentially testing the framework (e.g. index action rendering index template) or were a mix of controller and view tests that were brittle and not as comprehensive as a Capybara feature spec.

Taking a ri approach, I have adapted my practices to do more outside-in tests.  These have the advantage of reinforcing the customer experience and keep me from diving too deep too soon.  They allow me to explore the data relations and behaviors before getting in to specifics about the low-level details.

It is interesting to note that in researching the talk, I could not find many (if any) controller tests in the current edition of Hartl tutorial.

LinkedIn

The third phase of the talk took a bit of a left turn, but I think is an important lesson for someone trying to break into the field.

I am a big believer in REAL networking, i.e. talking to people, building relationships, asking questions, and following up.  I have made some awesome friends, mentors, and mentees in the Rails community.  It took me too long to learn how to effectively meet people and build relationships.  Fear and imposter syndrome are tough things to overcome.

I see a lot of people not networking effectively and it makes me sad.  We had a really good discussion about getting out and talking to people, sending follow up/thank you emails, and personalizing your LinkedIn invites so the person on the other end remembers you and is inclined to accept your invite.  A big key is following up, if you make a contact at a meetup, say hello at the next meetup, ask a question about something they told you about themselves, be genuine.

As always, it was great to meet another Launch Academy cohort.  I hung around for quite a while and the Launchers had awesome questions.  Looking forward to seeing them out in the community soon.

Facebook URL Linter, Critical Errors, and Rackspace

When you share a URL on Facebook, Facebook will scrape the page to find the Open Graph data embedded in the page.

Facebook also provides a tool called the Open Graph Object Debugger to help you debug errors found in the page.  This can be rally useful if, for instance, your tags are not well-formed, or there are problems with the images or videos that are on the page being shared.

Sometimes, unfortunately, you get a dreaded “Critical Errors That Must Be Fixed – Error Linting URL” as shown below.

UrlLinterCriticalError

Unfortunately, this doesn’t tell you a lot about the cause of the error.  I was trying to have an image display using the og:image tag.  I had been able to successful share pages that had images that were in my Rails  asset directory, but this particular page used an image that was hosted on Rackspace Cloud Files.

To try and diagnose whether there was a problem with the image (e.g. corrupt file, invalid size for Facebook, etc) I downloaded the image and stored it in my Rails assets.  Everything worked fine.  No errors from the Facebook URL Linter.  The problem must have something to do with the storage on Rackspace.  But browsing to the image on Rackspace worked fine as well.  The image displayed fine in the browser and was publicly accessible.

Why wasn’t the Facebook URL Linter able to parse it?
Well when you store files with Rackspace Cloud Files, you get a pretty hideous URL, like

http://12345678901234567890-12345678901234567890123456789012.r12.cf3.rackcdn.com

A URL is a URL right?  Well yes and no.  I think the Facebook URL Linter finds this to be a pretty suspect URL and considers it spammy.  So I needed to make the URL a little more “friendly” to a spam filter.

The answer was to use a CNAME to map a more readable URL to the Rackspace URL.

My client’s site is hosted on GoDaddy, so that meant going into their DNS settings and adding a CNAME record to point to the Rackspace URL.  I picked something meaningful like “images”.  So now my og:image tag could change from

<meta property="og:image" content="http://12345678901234567890-12345678901234567890123456789012.r12.cf3.rackcdn.com/some_image.png">

to

<meta property="og:image" content="http://images.mydomain.com/some_image.png">

In hindsight, the CNAME is a good idea on its own. Sure it might be an extra hop to get the image, but having a more logical URL makes a lot of sense, and it also makes in easier to change where your images are stored.

Reinventing Yourself at Boston Ruby

I gave a talk at the November 2013 Boston Ruby Meeting about my experience moving back to a development role after working the last few years in more managerial roles in the medical device/laboratory automation space.

My hope was that this talk would help people starting out in the Rails world, or perhaps people who are transitioning to Rails from the Java or .NET worlds as I was.

Along the way, I also talk about ways to establish yourself in a new development community and how to build up your network beyond just adding people to your LinkedIn network

Rebirth of the PWA – Mentors Wanted

I had a shitty job once.  I know, hard to believe, it must be such a unique and rare experience.  Don’t worry recent employers, it wasn’t you.  It really was a long, long time ago in a galaxy far, far away (the ’90s).

I won’t bore you with the particulars, but something interesting grew out of it.  One day while walking with some co-workers at lunch, we came across a previous co-worker who had left the company for greener pastures. We all unloaded our woes on this poor unsuspecting chap, how bad things were, how much we hated it. It was pretty pathetic.

After we parted ways, my current co-workers and I realized how we had let ourselves slip. Sure our jobs sucked and our boss was a lunatic (he really was) but that was not an excuse for letting things get so far. We made a pact that day that we would find ways to make things better, if only for ourselves.  And so we formed the PWA, the Positive Workers Association.  We would encourage one another to build our skills and make our work lives generally better. We set goals and held each other accountable. These goals were all things that helped us at our current job, so it wasn’t like we were learning Italian to pass the time.

My company uses the 37 Signals product Know Your Company.  Today’s question was “Is anything holding you back from doing the best work you can do right now?”.  My answer covered a lot of ground, but one area that I touched on was that the things I was doing to learn and grow lacked planning and a road map. I invest a lot of time into being better at what I do, and the last few years have been about getting better as a web developer, specifically in Ruby.

But where do I go now? And who is going to call bullshit on me when need be.

So maybe it is time for a rebirth of the PWA, specifically I think it is time to build some new mentoring and peer relationships. Good relationships go both ways, so hopefully you are also interested in finding ways to improve yourself and would benefit from a sounding board or a bullshit caller.  If you are interested, I’d love to connect with you, especially if you are in the Boston area.  Ping me on the twitters or contact me mdenomy at gmail dot com.

Wicked Good Wrap Up

What an amazing weekend at Wicked Good Ruby, where does one begin.

Thank You Brian, Johnny, Sean, and others

First things first.  Thank you Brian Cardarella, Johnny Boursiquot, Sean Hussey, and all the volunteers for making Wicked Good Ruby happen.  I remember being at the Boston Ruby meetup where Brian announced that he was organizing Boston’s inaugural Ruby conference. We all cheered wildly…then we went home, while Brian, Johnny, Sean and others did the hard work.

Kicking Us Off

Liana Leahy got us kicked off in song, reprising the role of Ruby Minstrel.  Liana has a great gift both vocally and satirically.  And if this Ruby thing doesn’t work out for her, I’m sure she could pursue other avenues

Opening Keynote

I was really excited when it was announced that Sandi Metz would be giving the opening keynote.  She promised to tell our future.  Along the way she took us from ancient scrolls on papyrus, to the Roman codex, handwritten manuscripts, the Gutenberg printing press, right up to the linotype machine.

Sandi shared some childhood memories of her dad, who worked for a newspaper in Parkersburg, WV, who started out working with linotype machines but managed to re-invent himself when the printing world changed in 1965 with the advent of photosetting and the sudden death of linotype machines.

She gave us some hard truths about life, we are going to die, but also reminded us that we need to live and love along the way.  I can’t do justice to Sandi’s words so look for the talk online later.   I was blown away.

Awesome Talks

I won’t try to go over all the talks, though there were a few that I really liked.

Joanne Cheng taught us how to play and explore with Ruby-Processing, showing some truly amazing ways she has used it to visualize data and just have fun.  I liked that she shared unexpected lessons that she learned along the way, becoming a better programmer, gaining confidence.

Mike Nicholaides reminded us about ways of securing our Rails app.  Stuff we should all know, but I know I left the talk thinking about some of the tests I am going to write this week to test for holes in my apps.

Neeraj Singh pointed out some of the “good” and “bad” magic of ActiveRecord.  His talk made me want to rush home and play around with different “features” of ActiveRecord that we take for granted work a certain way.  Understanding how they really work can save you a lot of pain.

Dan McClain had some really awesome ways to let your app take advantage of the advanced datatypes in PostgreSQL.  Dan obviously knows a ton about the internals of PostgreSQL, but he made things very clear and easy to use.  Another talk that makes me want to experiment and grow as a developer.

Matt Aimonetti talked about “good” code and “bad” code.  I was psyched that I got a question in that got kicked around by Matt, Sandy Metz, and Katrina Owen in the round-table discussion.

I wish I had more than 140 characters to ask a fairly nuanced question about what is the right amount of testing for a Rails app.  Fortunately I got a chance to catch up with Matt just before the conference ended to explore some ideas.  I love how approachable people are in this community.

Things to Consider

There were a lot of local developers at the conference, which was really nice to see.  I know a lot of the companies and developers from helping out at Boston Ruby.  One disappointing trend I saw was people sticking with their co-workers.  Sure it gives us a common understanding that we can take back to the office, and we don’t need to reach outside our comfort bubble and engage people we don’t know.  But that’s the best part of a conference.  Meet new people, learn what they are passionate about, share your experience.

Along those same lines I wish there was a little bit more time between talks.  It’s a balance between getting as much great content as possible but also having a chance to talk to other devs, or dare I say it, approach a speaker and say hello.  I really enjoyed talking to Matt Aimonetti, Neeraj Singh, and Mike Desjardin about their talks.  The short time between talks also made for some rushed moments when a speaker talk inevitably ran long.

Finishing Where I Started

Thank you Brian, Johnny, and Sean.  You guys kept things flowing and from where I was sitting it looked like everything went off smoothly.  I am sure there was furious activity behind the scenes, but it looked like a well oiled machine.

And thank you volunteers.  Working the registration table, arranging sponsors, sending out emails, and coordinating the speakers and attendees is a mostly thankless job, but let me say this.  Thanks :)