Author Archive

VIDEO: Here’s a demo of some thoughtful UI on Ffffound.com. »

Here’s a demo of some thoughtful UI on Ffffound.com.

QUOTE: One thing to remember in economics is that »

One thing to remember in economics is that you can’t do one thing in economics. There are always other effects that come out of it.

Warren Buffett. This issue of interconnectedness often comes up in software design too. Today’s performance tweak or new feature is tomorrow’s design constraint. Also reminds me of side-effects in functional programming and why ‘purity’ in code can be such an attractive windmill.

PHOTO: Flash hiccups aside, the latest incarnation »

squarepusher-site.jpg

Flash hiccups aside, the latest incarnation of Squarepusher’s website is still bold, fresh and interesting. I like the trend that’s grown steadily over the last couple years toward background elements that stretch to reach the vertical or horizontal bounds of the browser window. The combination of stretchy elements and fixed elements produces a figure/ground relationship that adds depth to the site and makes it more immersive.

PHOTO: squarepusher-site.jpg »

squarepusher-site.jpg

Flash hiccups aside, the latest incarnation of Squarepusher’s website is still bold, fresh and interesting. I like the trend that’s grown steadily over the last couple years toward background elements that stretch to reach the vertical or horizontal bounds of the browser window. The combination of stretchy elements and fixed elements produces a figure/ground relationship that adds depth to the site and makes it more immersive.

Crusty Gold: Basecamp’s footer badge »

A few weeks ago at our Maine meet-up, David was telling a story about preparing for his latest RailsConf keynote. His plan was to talk about bad code from our own apps*, and we were cracking up when he explained his hunt for all that “crusty gold” buried in our repos. I ran into my own nugget of crusty gold today while taking a peek at Basecamp’s footers.

The footer of each page in Basecamp may show a badge that says “Managed with Basecamp.” I wanted to figure out when and why that badge is displayed. So I found my way to the relevant template and saw this:


<div class="Footer">
  <% if @account.free? || @account.show_footer_badge?%>
    <a href="<%= @account.free? ? "http://www.basecamphq.com/?ref=free" : affiliate_link %>" target=_blank>
      <img align="right" width="112" height="30" src="/images/poweredbybasecamp.gif" alt="Powered by Basecamp" border="0" align="absmiddle" style="margin-right: 8px;" />
    </a>
  <% end %>
</div>

The first order of business was the question: Under what conditions do we show the badge? The first condition, @account.free? is clear enough (it means the account is on a Free plan). But what’s up with the second condition: @account.show_footer_badge?

Since the method is on @account, the first place I checked was our Account model. But it turned out that show_footer_badge? isn’t a method. It’s a column on the database. That meant I had to find where that value was being set by the user and saved into the DB to figure out what it really ‘means’.

Some grepping revealed that show_footer_badge? is actually a relic from our first BC affiliate program. People on this old program had the choice to check a box to hide or show the footer badge to all their employees and clients using their Basecamp account. What’s crusty about this? The problem is that @account.show_footer_badge? gave me no indication that this is really about affiliate settings. A simple change to the name of the method would have really clarified that:


  <% if @account.free? || @account.affiliate_wants_to_show_badge? %>

This comes back to a favorite design pattern: Intention Revealing Interfaces. @account.show_footer_badge? says what to do, but it doesn’t reveal the original author’s reason or intention.

To round out this nugget, let’s improve that nasty anchor and image tag from the first excerpt above. We’ll use a Rails helper and some CSS to clean things up:


<div class="Footer">
  <% if @account.free? || @account.affiliate_wants_to_show_badge? %>
    <%= link_to basecamp_url_with_affiliate_code, image_tag('poweredbybasecamp.gif'), :class => 'affiliate_badge' %>
  <% end %>
</div>

The next time we go digging into Basecamp’s footers, this code will be a lot easier to understand.

Related: Behind the scenes: Redesigning and coding the Highrise sidebar modules, What belongs in a helper method?

VIDEO: This promo video for SoundCloud shows how »

This promo video for SoundCloud shows how much style you can inject into a screencast. You can tell they are speaking directly to a certain audience through their attitude, visuals and music. I particularly like how they intentionally show some purple desktop background around the browser window. Screencasts often look the same when you don’t see anything beyond the edges of the browser window. Well done guys!

VIDEO: This promo video for <a href=”http://soundcloud »

This promo video for SoundCloud shows how much style you can inject into a screencast. You can tell they are speaking directly to a certain audience through their attitude, visuals and music. I particularly like how they intentionally show some purple desktop background around the browser window. When you crop in on the browser content, every screencast looks the same. Well done guys!

It’s the small touches that won me over. »

It’s the small touches that won me over. Well designed, a bit of attitude, and useful.

—App store reviewer Jragon on Sketches. Should good software have ‘a bit of attitude’?

Rails tip: Use subdirectories to namespace »

Rails tip: Use subdirectories to namespace images by resource. Eg. images/people/add.gif vs. images/companies/add.gif

Ryan

Ryan speaking at Future of Web Design in NYC November 3-4 »

Once again I’ll be speaking and giving a three-hour workshop at Future of Web Design in NYC this November 3-4. The workshops especially are a lot of fun.

What would you like to hear me talk about? Please post your ideas here or email ryan at you-know-where dot com.

I’d love to see you in New York, and especially hear your questions and ideas.

How to manage long breaks in your software side projects »

Pablo Corral wrote me an email after I posted this tweet about managing on-again-off-again side projects.

I’m very curious about how to use Backpack to have a better experience on braindumps for side projects.

I switch a lot, and my side project sometimes is off for many days, and some weeks. Can you explain more about this?

It’s hard to find steady uninterrupted time for software side projects. Maybe you only have time on weekends or the occasional free night for your project, and sometimes weeks or months go by where you are too busy to sit down and make some progress. When you finally do find time to work, you can waste half of it just catching up on where you left off.

This has been a big challenge for me because one of my projects is a Rails app that supports registration and administration for a biannual retreat course. Four or five months may go by before I return to the app for another course, and with each course there are new bugs to fix or feature requests to implement. A couple years in this situation have helped me develop a system to manage my side projects with a minimum of headaches and wasted time.

My system is a one-two punch: Hosted version control plus a single Backpack page. These two are all you need to keep the state of your project off your brain and at the ready.

First punch: Hosted version control

Sign up with a hosted version control service like GitHub for Git or Beanstalk for Subversion. I advise using version control even for static websites.

There are two key benefits to hosting your source with these services. First, your source is independent of your work machine. If your machine crashes, you replace it, or even if you space out and delete some things you shouldn’t (that would be me), your code will always be safe and secure in the online repository.

The second benefit is an easy-to-read commit log. With one click you can visit a bookmark and see a timeline of changes you’ve made to the code in chronological order and in your own words. Just glancing at the commit log can be enough to jog your brain after a long absence and bring you right back into the project.

Second punch: A single Backpack page

I make a single Backpack page for each project with two lists and some notes. The two lists are ‘To-Do’ and ‘Debt.’
The ‘To-Do’ list is for things I really, truly, honestly plan to do next. I keep it very short, always less than five items. If it gets any longer, I’m probably fantasizing instead of actually planning to do those things. Whenever I return to a project, the top item on the To-Do list tells me what I should work on.

The ‘Debt’ list is for things I should have done but didn’t bother to do. The Debt list is partly a psychological trick. It helps me cut corners without feeling too guilty. Should’ve added validations to that model? Add it to the Debt list. Wrote a condition without thinking too deeply about the edge cases? Just add it to the Debt list. But it’s also more than a band-aid for laziness. If something breaks or I run into some unexpected behavior, chances are a quick glance at the Debt list will point me to a corner that I cut or a step I skipped and lead to a direct solution instead of an hour of head-scratching.

Lastly my Backpack account is SSL protected, so I feel safe storing information about my production environment. I can never remember where a project is hosted, what the username and password are or if there are particularities with the configuration I should know about. I keep all this server info on a note at the top of the page, so each time I need to log in I don’t have to go digging for passwords or welcome emails from my host.

A powerful combo—when you hold up your end

All the lists and logs in the world won’t help if you don’t create some good habits. Commit frequently, and whenever possible write commit messages about your intention, not your implementation. Say “Fix the broken sidebar layout” instead of “Fix a typo in the class name.” The former will be a sharper hook to your memory later. For the Backpack lists, try to be brutally honest. A mile long To-Do list is proof of time wasted, not time saved. Focus your To-Do list on the next few things you need done, and limit your Debt list to Debt that actually matters.

This system has helped me organized my side projects and optimize the short slices of free time I can dedicate to them. I hope it works for you too. Let us know in the comments if you have any systems of your own for managing side projects over time.

Behind the scenes: Redesigning and coding the Highrise sidebar modules »

I’ve wanted to redesign the Highrise sidebars for a long time. They’ve felt cluttered and messy to me, and as we add more features to Highrise the mess will only multiply. So I was glad to have the chance this week to redesign the sidebar modules. The visual side of the redesign was straightforward, but implementing the design in code required a few tricks. Here’s a look behind the scenes at the coding decisions we made for the new Highrise sidebars.

“Subjects” in Highrise

Which sidebar modules am I talking about? In Highrise you can keep track of People, Companies, and Cases. These all have the same basic code and UI. You can keep notes about them, set tasks for the future, and manage some common types of metadata. Since People, Companies and Cases share so much plumbing, we’ve abstracted them as subjects. A subject is anything in Highrise that you can attach notes and tasks to. When you look at a subject’s page, you see a sidebar with some modules for adding or editing metadata such as contact information, background information (a kind of static text description), dates to remember for that subject, and more. The screenshot below shows a subject page with the sidebar modules highlighted.

Redesigning the modules

Each module has a header like “Contact Bob” or “Dates to remember” and data below. In the original design, modules can be either “active” or “empty” based on whether they have any data in them. Empty modules have a grey header and an “add” link floated right. Active modules have a light blue header and an “edit” link on the right. We made this distinction so your eye would more easily catch active modules when you’re looking for information. The idea was good, but the original implementation looked messy with its mix of grey and blue, scattered red action links, and lack of separation between modules.

For the first redesign (above) we cleaned up the modules. Active modules are now wrapped entirely in a light grey box with a tiny drop shadow. We killed the blue header style, relying instead on the space between modules to separate them. Empty modules no longer have a header. They are grey boxes collapsed down to a single link to add the content relevant to that module. Finally we replaced all the red links with grey links in order to put the focus on the data within active modules rather than all the possible actions. One last tweak: we changed the text for “About [subject’s name]” to “Add background information.” We’ve gone back and forth a number of times on the language for this feature, and at this stage we decided to try “background info” on for size again.

The first redesign was a big improvement. But we didn’t like the way active and empty modules looked mixed together. The dim bar in between those two active modules creates a kind of striped look that we want to avoid. The problem was worse on subjects with more sidebar modules, like companies or cases. So we decided to group all the active modules together on the top, and then group the empty modules on the bottom. The result is much cleaner, and it’s easier to scan when you load up a subject in order to quickly grab some info like an email address or birthday.

The re-ordered sidebar was a winner. But it came at a price. We couldn’t just change the CSS and call it a day. Now we also had to write code to re-order the sidebar modules dynamically based on whether they were empty or active. Ruby’s power and flexibility really came in handy for this job.

The code

I said earlier that people, companies, and cases are handled by the same plumbing because we abstracted them as subjects. The result of this abstraction is that whether you are looking at a person, a company or a case, the sidebar is rendered by the same template: subjects/_sidebar.rhtml.

(This kind of “view polymorphism” has been subject to a lot of internal debate since we first released the app. It makes maintenance both easier and harder because the code has less repetition on one hand but on the other it is less intention-revealing due to the abstractions and indirection.)

This is what the original template code looked like to render the subject sidebars:

in app/views/subjects/_sidebar.rhtml:

  <% if @subject.is_a?(Party) %>
    <%= render(:partial => 'parties/contact_info') %>
  <% end %>

  <% if show_company_contact_info?(@subject) %>
    <%= render(:partial => 'parties/contact_info', :object => @subject.company) %>
  <% end %>

  <%= render :partial => 'backgrounds/show' %>
  <%= render :partial => 'contact_dates/index' %>

  <% if @subject.is_a?(Kase) %>
    <%= render :partial => 'kases/parties' %>
  <% end %>

  <% if @subject.is_a?(Company) %>
    <%= render :partial => 'companies/people' %>
  <% end %>

Don’t worry too much about the individual partials and conditions. The key point is that each partial is a sidebar module, and each module is conditioned based on the particular subject we are rendering. A different mixture of partials will be rendered depending on whether the subject is a person, a company or a case, but they’ll always render in the same order.

We want to re-order these partials dynamically based on whether each module is active or empty. That means we need to represent the possible partials, the conditions for displaying them, and also the conditions for determining whether they are active or empty within some kind of data structure. So we popped open our Rails subjects_helper.rb and represented this information in an array.

in app/views/helpers/subjects_helper.rb:

  def sidebar_modules_to_sort
    returning [] do |m|
            # partial to render       module_is_active?                 options                          render the module for this subject?
      m << ['parties/contact_info'  , show_contact_info_module_on_top?, {}                             ] if @subject.is_a?(Party)
      m << ['parties/contact_info'  , true                            , {:object => @subject.company}  ] if show_company_contact_info?(@subject)
                                        #necessarily true per the condition at right
      m << ['backgrounds/show'      , !@subject.background.blank?     , {}                             ]
      m << ['contact_dates/index'   , @contact_dates.any?             , {}                             ]
      m << ['collections/parties'   , @subject.parties.any?           , {}                             ] if looking_at_collection?
      m << ['companies/people'      , @subject.people.any?            , {}                             ] if @subject.is_a?(Company)
    end
  end

The helper method sidebar_modules_to_sort returns a parent array full of child arrays, one for each module with an element for the template path, a true/false value to show if it is active, and an options hash for the render method. The conditions that used to determine whether each partial should be rendered now determine whether each child array should be included in the parent array. Thanks to that boolean in the second element of each child array, we can partition the parent array into two groups: those where the second element which represents that the module is ‘active’ are true, and those were that element is false. We use another helper method to partition and reassemble the array into groups.

in app/views/helpers/subjects_helper.rb:

  def sidebar_modules_in_order
    active_group, empty_group  = sidebar_modules_to_sort.partition {|m| m[1]}
    active_group.concat empty_group
  end

Finally we return to our sidebar template to do the actual rendering.

in app/views/subjects/_sidebar.rhtml:

<%= sidebar_modules_in_order.map {|m| render sidebar_module_partial(m)}.join %>

This line in the template takes the sorted array of sidebar modules and replaces each element in the array with the rendered partial. Then the join method converts each element to a string and concatenates them. sidebar_module_partial is a call to one more helper. This helper assembles the arguments for render out of the elements provided in the array. It looks like this:

in app/helpers/subjects_helper.rb:

  def sidebar_module_partial(m)
    m[2].merge({:partial => m[0]})
  end

In the snippet above, sidebar_module_partial takes the third element of each module array, which is either an empty hash or some special options for render, and merges a key specifying the template path onto that hash.

We definitely could’ve hidden these rendering gymnastics behind a helper, perhaps called render_sidebar_modules or something similar. However we’ve decided for style reasons to avoid calling render from within our helpers. Therefore we decided to use a helper to merely fill in the arguments to the call to render within the template itself.

In the end, we have a new sidebar design and some clean and intention-revealing code. This was a fun chance for me to expand my Ruby knowledge by dipping into the nuts and bolts of arrays and hashes. Thanks to Jamis for reviews and advice when I knew there had to be “a better way.” We hope you enjoy the new sidebar modules in Highrise.

Related: What belongs in a helper method?

Modal overlays beyond the dialog box »

Aza recently posted on modal overlays, those dialogs that pop up and disable the background behind them. You can click anywhere inside modal overlays, but you can’t click anything in background until the dialog goes away.

Usually when we think of modals, we think of dialog boxes like the one below from Google Documents. Aza’s critique applies to this kind of modal. After you call up the find/replace box, you can’t click anywhere but inside the dialog. That means you can’t scroll the document underneath the dialog or copy and paste a word from the document into the dialog box while the dialog box is displayed.

But that’s not the only kind of modal overlay. Check out this Preference pane from Apple’s Me.com. It has nothing to do with modifying the content behind it. It could just as well be a separate screen.

Actually, this fact that it could be a separate screen caught my interest. At 37 we never use modal overlays. All our settings screens are completely independent from the other screens in the app. In order to explore the difference between these two approaches, I mocked up an alternate version of Apple’s preference screen that fills the entire window like a typical web app might.

It’s interesting to compare these two versions. I have to admit I like the modal one a lot better. On the one hand it has more visual interest and depth. On the other, it raises some interesting questions about navigation.

Modals as alternatives to navigation

Two questions that often float in our minds when we use software are “Where am I?” and “How do I get back?” There are common techniques we use to ease these concerns like tabbed interfaces, breadcrumbs and “Cancel” links. We should think of the modal overlay as a tool in the same family. It is uniquely powerful at quieting these nervous questions. “Where am I?” is a non-starter because you never left the original screen. And “How do I get back?” is trivial when the original screen remains visible in the background.

Screen size as a reflection of importance

Another thing I like about the modal approach to Preferences is that the preference screen doesn’t feel equal to the other application screens. You get the feeling it didn’t deserve its own browser window’s worth of real estate.

When we design the UI for a particular screen we always try to make the important and frequently-used elements larger and more prominent than the lesser-used elements. It’s a good rule of thumb to think that if elements in the same context all have the same size, then they must be equally important. Apple’s Preferences modal applies the same principle to the scale of entire screens. The preferences screen is itself smaller than the browser window that plays host to the more important screens full of real data.

Modals aren’t all bad

While Aza’s critique still holds for modals like the Google docs example above, Me.com demonstrates that modal overlays do have a place as an alternative to navigating between independent screens. It’s also very interesting to consider which screens really deserve their own browserful of real estate and which should be reduced to substates of other screens. I suspect that when people praise applications for being particularly “Ajaxed” or “Desktop” in style, this lack of navigation between separate screens is a big part of the appeal. Apple has shown that it’s possible to bring desktop-style interactions into web apps without falling into the extreme of a desktop clone. It should be fun to see where other designers take the inspiration.

New color picker in Basecamp »

Creating color schemes in Basecamp just got easier. Before, you had to understand complicated hex codes to customize your colors. Now anybody can choose colors with a shiny new color picker. Kudos to Sam for the extra attention to detail on the color picker. We think it’s solid and it’s the best color picker we’ve used on any web application. Picking colors in Basecamp is a lot of fun thanks to the live feedback, so load up your Settings tab, click “Color Scheme” and take it for a spin.

New in Basecamp: Updated People and Permission screens »

Today we released some improvements to the People and Permission screens in Basecamp. We’ve improved the process for adding new people to a company within a project and we redesigned the Permissions screen with a number of subtle usability improvements. You’ll also find a new Administrators screen to easily control which people in the account holder’s company have Administrator powers. Check out the video below to see the changes.

The redesigned Permissions screen wasn’t really a redesign. 90% of the screen looks and works the same. We worked a lot with subtle changes in text size, positioning, and color in order to bring more clarity and spaciousness to the screen.

Here’s the old version:

And the new redesign:

Some quick highlights:

  • The old screen has red links scattered all over. It made the page feel messy. The new design only uses red for the “Add a new person” links.
  • We replaced the red “Add a company” link with a graphic button. We reused some code from Highrise to smoothly transition between the button and the “Add a company” form.
  • The old screen loosely employed a tab metaphor in the blue header. The phrases “People on this project” and “Change permissions” always appeared in the header, and one phrase would be linked while the other was regular black text depending on the page you were viewing. In the redesign, we decided to think of “Change permissions” as a process you enter and leave. We renamed that action to “Add people, remove people, and change permissions.” Now the entire blue header is devoted to this action, and there is a blue “Go back” link below the header to return to “People on this project.”
  • We bumped up the font size on peoples’ names and wrapped them in <label> tags. Now each name is a generous mouse target. We did the same for the radio buttons that appear to the right of people with access to the project. Clicking around is much nicer now.

We played with a number of wilder revisions before settling on these very subtle changes. Sometimes the hardest part of redesigning something is realizing where you had it right in the first place. We hope you like the changes.

Soundcloud expands the audio player »

Most embedded audio players offer a tiny player with the basics: play/pause and a progress bar.

While this design works great for the casual listener, Soundcloud has another audience in mind. Musicians, producers and sound engineers want to do more than listen to a track. They want to provide feedback on specific details. The bass at 2:36 needs more compression. There’s a mic out of phase at 4:01. Can we try another patch for this one chord in the bridge?

In order to allow this kind of collaboration, Alex and the guys at Soundcloud could have used a standard player and tossed a comment stream below it. Instead they decided to expand the player and allow commenters to add notes directly inside on the waveform itself. The result is pretty cool. People can post tracks and receive a flurry of comments attached directly to the waves.

The player spans the full width of the screen, so it’s easier to set the playhead at the exact spot you want. Commentor’s avatars appear in the bottom of the player, and their comments pop up on hover.

I like how these guys set out to build a collaboration site for music makers, and what did they concentrate on? The music player. It cuts straight to the epicenter (more).

They also scratched my persistant itch for larger link targets in their “Actions” section of the sidebar:

Soundcloud is still in private beta, but Signal vs. Noise readers can check it out with this link: http://soundcloud.com/guestlist/signalvsnoise .

Learning from “bad” UI »

When Gruber first linked the TripLog/1040 UI by Stevens Creek, I wasn’t kind either. Bright colors, controls seemingly placed at random. It was the opposite of what designers strive for in our circles. A mess. Soon the Flickr page was a schoolyard of insults. And then something interesting happened. TripLog’s designer Steve Patt posted a comment amidst the bile to share the rationale behind his design. The many who chose not to listen to him won’t learn anything, but the rest of us may find fruit in Mr. Patt’s thoughtful explanation and twenty years of software experience.

The first charge against TripLog is “clutter,” that there’s too much on the screen at once. We’ll get to clutter, but first we have to talk about speed. Patt explains that the #1 purpose of TripLog is to help people track their deductible or reimbursable mileage. If people can’t enter their trips very quickly, the friction of entering data will overpower the motivation to track. For customers, untracked data means miles that aren’t reimbursed. So speed is Patt’s top priority.

What does speed have to do with clutter? I once saw Tufte give a workshop in Chicago where he introduced a valuable concept. He said information may be displayed adjacent in space or stacked in time. Take a book for example. If two dots are on the same spread, they are adjacent in space. All it takes to switch between them is movement of your eye. Compare that to a dot on one page stacked above a dot on another page. You can’t see them at once. You have to flip back and forth between pages to see one dot versus the other.

The trade-offs between elements adjacent in space versus stacked in time are always in the mind of a UI designer. Placing many elements on the same screen reduces the need for navigation and gives users a comprehensive feeling of “it’s all at my command.” Moving focus from one element to another is instant and seamless. On the flip side, separating elements onto different screens slows things down with navigation while increasing clarity. There is more room for explanation and luxurious space when fewer elements occupy the page. The eye has less to filter through. The course of action is more obvious.

So did Patt put too many elements adjacent in space on one screen when he should have separated them out in time? Is his UI “cluttered?”
To answer that we should pull ourselves out of the computer and sink our feet firmly in the customer’s shoes. Patt explains that customers load the application for two reasons:

  1. They want to log miles they just drove
  2. They want to double-check that they logged a recent trip

The first is obvious. Patt explains the second:

There’s a very simple reason, which we know because we’ve been selling our Athlete’s Diary software for logging a different kind of mileage for nearly 20 years. It’s because when you start up the software, half the time you’ll be scratching your head saying, “Did I remember to enter yesterday’s ride (or run)?” … You want to be able to answer that question immediately, with just a quick glance down to the bottom of the screen.

Half the time people want to add new entries. Another half of the time, people want to verify a recent entry. On top of that, people also like to confirm the accuracy of data after they submit it. These factors together form a motivation to place the “add an entry” and “verify recent entries” features adjacent in space. It’s a decision to optimize for instant access to both features at the cost of showing more elements on screen at one time.

Beyond first impressions

When we talk about “usable” or “intuitive” interfaces, Apple devotees and the web app crowd (myself included) tend to bias toward the first-time user. The idea is an interface is easy to use if new users can figure it out and get running quickly. Or an interface is “clear” if all the parts and functions can be immediately parsed upon eye contact. Typically this means stacking features in time so that each screen has fewer elements and is easier to digest. TripLog, while far from perfect, has a different focus. Rather than first-impressions, Patt is thinking about repetition. Spatial memory and adjacency play a major role in repetitive tasks. How many of you keep an assortment of pens, papers, and peripherals on your desk in specific positions instead of moving them in and out of drawers every day?

Patt’s bias for adjacency and speed continues inside the “Add an entry” block. There are two ways to log a trip: manually enter data in the fields or choose user-defined presets called “Frequent Trips.” Both methods are exposed. However everything can’t be exposed all the times. There are some features stacked in time too. Choosing a date “Other” than Today or Yesterday, selecting a different Car (for IRS purposes), and editing the Frequent Trips list are all behind the time wall and require navigation.

So what did we learn?

The fact that a screen is “cluttered” doesn’t automatically mean it is poorly designed or ill-conceived. To many of us, screens thick with adjacent elements are like cold water we prefer not to step into. The very fact that TripLog is no feast for the eyes attests to the difficulty of bringing clarity and order to a screen relying too heavily on adjacent features. It would be a fun exercise to redesign TripLog for more visual clarity without removing any elements.

However before we criticize we should look for successes. Where TripLog fails on style it may well win on speed and pragmatics. Patt has thought about his work and designed a product intentionally. Following fashion and the status quo is easy. Thinking about your users’ lives and creating something practical is much harder. Patt can work on his colors and alignment, and hopefully please his user base with a helpful tool. Meanwhile the rest of us would be wise to work on the quality and value of our criticism.

Features are a one-way street »

Here’s another reason to double, triple, quadruple-check yourself when you want to add a new feature. A while back Netflix added a “Profiles” feature to their service. A couple weeks ago, they decided to pull the feature because it was too confusing and it wasn’t adding value. But it was too late. People were pissed. The blog post received 1286 comments. In the face of this reaction, Netflix had to turn 180 and keep the feature. Whether Netflix Profiles are good or bad, clear or confusing, they’re here to stay.

The lesson: Once your user base has grown beyond a certain point, you cannot take features away from them. They will freak out. Whether the feature is good or bad, once you launch it you’ve married it. This changes the economics of feature additions. If you can’t destroy what you build, each addition holds the threat of clutter. Empty pixels and free space where a new feature could be added are the most valuable real estate on your app. Don’t be quick to sell it, because you can never get it back.

Fresh UI ideas from Songza and Algorithm Ink »

Aza Raskin released a new project today called Algorithm Ink. For the full story check out his explanation and video. The app is basically a “grown up version of Logo”—a front-end to a simple programming language for creating fractal images. While the fractal art is the main attraction, I was more interested in the unconventional UI.

Algorithm Ink continues the style that Aza demonstrated six months ago with Songza. His UI comes from another planet where Microsoft Windows never caught on and Hypercard rules the world. There are no native form widgets, no scroll bars, and nary a “ or Cancel” in sight. Normally this is a recipe for confusion, but in Aza’s case the results are often models of clarity and intentionality.

On Songza, the most noticable break from convention was the mouse-flower. Traditionally, a web UI for playing a song would consist of the song’s title, a widget to play/pause, and some adjacent links to share, rate, etc. Instead Songza only shows the song title. When you click the title, a flower opens with an action on each petal like “Play” or “Share.” You can click a petal or mouse away from the flower to dissolve it. The jury’s still out on mouse-flowers, but the clutter-free UI they enabled should raise an eyebrow.

On Algorithm Ink, the header is what interested me. Each of the grey buttons (Edit, Save, Browse, etc.) is actually a toggle between an “on” state and an “off” state. When a button is “on”, a panel appears on top of the canvas with the functionality for that button.

The grey buttons toggle overlaying panels

For example, when you click “Edit”, the button turns on and a panel is revealed with the code for the current artwork. You don’t “Save” or “Cancel” to leave edit mode. Instead you click the red “Draw” button to apply your changes, or click Edit again to hide the panel.

The Edit button is on and the panel is visible

Each of the buttons has its own custom panel. Edit displays a long narrow sidebar, while Save displays a thin horizontal strip. It’s note-worthy when different features of an app actually look different. We’re all guilty of leaning on our templates to the point that each screen in our apps looks a bit like the others. In Algorthim Ink, the Edit mode is tall and narrow. The Save mode is wide and thin. These differences give the app character and also help users develop a kind of “muscle memory.” They can remember the screens by shape as much as by name.

The Save button is on and the panel is visible

My favorite thing about these grey buttons is that they don’t just turn panels on and off. They also exclude each other, so that if you are using the Edit mode and you click the Save button, the Edit panel will disappear and the Save panel will replace it. You could say the buttons are “mutually-exclusive modes”. A simpler way is to say they act just like tabs.

Look closely at how a typical tabbed interface works. You click a tab, and the whole screen reloads to a new screen. The tab bar on the new screen has the same options and position as the old screen, except the tab that you clicked changes appearance to indicate that you are “on” this tab to the exclusion of the other tabs.

In Algorithm Ink, the buttons work in exactly the same way. Except there’s a twist. The “tabs” (grey buttons) don’t replace the screen, or even replace part of it. Instead they hide and reveal panels which overlay a single screen that never changes. Your art never goes anywhere, but the panels which allow you to perform actions come and go.

These overlay tabs may not be as eye-catching as a mouse-flower, but I think they’re very interesting. It’s hard to put my finger on what exactly I like so much about Algorithm Ink, but it’s plain to see that the approach is different. And in our current UI climate, well-executed difference is itself enough to deserve some thought.

What belongs in a helper method? »

I’m working on some improvements to Basecamp, specifically the screens where you manage which people have access to a project. There’s an area on our new template with checkboxes beside peoples’ names so you can check which people should be added to your project. I want to apply a class name to the label tag around the checkbox for each person. So I pulled up the template and searched for “label” to find where I might add the class name. There were no matches. So I dug deeper, and saw that the HTML for the label, checkbox, and person name is being generated by a Rails helper method.

This is the template code that calls the helper method.


<% people_without_access_from(company).each do |person| %>
  <%= add_person_to_project_check_box(person, company) %>
<% end %>

Next I pulled up the helper method to see if it really is responsible for producing a chunk of HTML with the label and checkbox.


def add_person_to_project_check_box(person, company)
  content_tag(:label,
    check_box_tag("people_ids[]", person.id, false, { :class => "company_#{company.id}_person" }) +
    " " + person.name
  ) + tag(:br)
end

Yup, it’s generating the HTML. Right away this smells bad to me. The helper is first generating a label tag. Inside that label, there is a checkbox followed by a space character and the person’s name. Finally a break is appended after the label. This smells bad for two reasons. First, it’s just not so nice for helpers to cook out HTML when they don’t have a good reason to. Second, it’s harder to locate and change HTML when it’s hidden inside a helper.

Returning to my original goal, I wanted to add a class name to the label around this checkbox. If I add the class name to the existing helper, it’s going to get even more messy and complicated because I have to give content_tag an attribute with the class name I want. It would look like this:


def add_person_to_project_check_box(person, company)
  content_tag(:label,
    (check_box_tag("people_ids[]", person.id, false, { :class => "company_#{company.id}_person" }) +
    " " + person.name
    ), :class => 'checkbox') + tag(:br)
end

To find a better solution, we should rethink what the helper should be responsible for. Helpers are useful when they hide complexity that isn’t relevant to the template. Looking at this helper method, I see that it’s useful to hide away check_box_tag with all those params. But the label, the break, and even the person’s name could all be in the HTML and the template would be clearer. Let’s do that.

Here’s the new helper. Now it only produces the checkbox.


def add_person_to_project_check_box(person, company)
  check_box_tag("people_ids[]", person.id, false, { :class => "company_#{company.id}_person" })
end

And here’s the updated template code, with the label, person name, and break moved over.


<% people_without_access_from(company).each do |person| %>
  <label class="checkbox">
    <%= add_person_to_project_check_box(person, company) %> <%= person.name %>
  </label><br />
<% end %>

Now that’s a lot easier to read. Generally speaking, it’s a good idea to keep your HTML in your templates and out of your helpers. Helpers are useful when they hide implementation details that are irrelevant to your template, or when they allow you to abstract common template code to avoid repetition. If you find yourself generating a lot of HTML in a helper, think twice and try to keep as much HTML in your template as possible.

Generous link targets in the library »

I love me some padded link targets and today’s provider is a Working Library.

The site is about books and their connections. Each post references one or more books and the referenced books are aggregated in the right-hand sidebar. When you hover over a book title, the crisp tiny type is immediately enveloped in a big cozy hover block.

I particularly like how the hover reinforces the column dimensions. It’s a sudden punch of structure to the otherwise airy layout.

(Found via JSM’s oddities)

Designers who also develop have more power »

Alan Taylor of The Big Picture proves how designers who can also develop are able to get things done without jumping through hoops of approval, explanation, and cycles of review.

In an interview at Waxy.org, Alan talks about how The Big Picture came to life within the Boston Globe.

I have an advantage in that my main role is as a developer here, so I could build all my own templates, format my own style, and so on. I sort of bullldozed some things through though, like extra width, few ads, and I made it simple internally by doing it mostly on my own, no requests for development time, marketing or promotion. After the legal questions were settled, I was free to try it out. It took off fast.

This is another example of why I strongly advocate that designers build development skills into their kit. When you’re able to do things yourself, you can just do them. You don’t need anybody’s approval or anyone else’s time. And sometimes that makes the crucial difference between an unimplemented idea or a great success like The Big Picture.

Patience as a design principle »

One of my intellectual heroes, Ronald Langacker, recently released a new book which summarizes his 30-year-old program of Cognitive Grammar, a radical and insightful approach to understanding language. In the very beginning of the book, Langacker outlines three principles which guide his work.

Integration means his explanations about language shouldn’t stand alone from our understanding of how the brain works or how psychology works. He wants his analyses to fit with neighboring disciplines instead of standing in their own tower.

Naturalness is his second principle. It means that a really good explanation should be reasonable and understandable. If an explanation is arcane, artificial, or exotic, it’s probably wrong.

Patience is an unexpected final principle. Being sure not to put the cart before the horse, it means withholding judgment on questions that are premature. As software designers, this means developing a “wait and see” approach that doesn’t indulge in too much speculation. Most feature ideas are speculative. “Wouldn’t it be cool if (x)” is very different from saying “for the last two weeks I’ve been frustrated by (y).” Having patience means putting speculative ideas on a shelf until actual life experience proves they have benefit. Launching a product with “too few” features is a kind of patience. Keeping your team small is a kind of patience.

At 37signals, we focus on lean features, short iterations, quick wins, small improvements, and the satisfaction of “build and release.” Paradoxically, all this quick movement and quick satisfaction rests on a foundation of patience. Most of our ideas are never implemented. Our products are never finished. Doing what’s in front of your nose, doing smart work that makes an impact today and leaves space for changes tomorrow takes patience. I’m glad Langacker’s book pointed this out.

Ryan talks design on the Rails Podcast »

I just got back from RailsConf in Portland. It was really fun to be a designer among a sea of programmers. I spent a lot of time talking to programmers about what designers do on a Rails team and how we should work together. A number of those ideas worked their way into an interview with Geoffrey Grosenbach of PeepCode. Listen to the podcast at Rails Podcast.

UPDATE: Here are some quick video interviews with Ryan, Jeremy, and David from RailsConf 2008.

Ryan Singer

Jeremy Kemper

David Heinemeier Hansson

Padded link targets for better mousing »

Among the minor tweaks we introduced with the new Basecamp project switcher are some larger link targets at the top of the screen. Since then I’ve been paying extra attention to link target size. Here are a couple examples of generous link targets for inspiration.

Threadless has featured large link targets on its main navigation for a long time. Here’s what the nav looks like:

Threadless links

As a user, when you glance at this nav, you might imagine the specific pixel areas that you need to target like this:

But when you move your mouse toward the nav, you’ll be pleased to discover the actual link targets are much larger:

The end result is a feeling of comfort. It’s just really easy to click the links. It feels like the links are working with you instead of against you.

Flor does the same thing with their links. Here’s the navigation:

Here are the targets you might aim for:

And here are the actual targets:

You might have noticed both of these sites use images for their navigation links. The same effect is easy to achieve with HTML links. Just use padding where you might have had whitespace.

Normally you might have white space between your links like this:

<div class="nav">
  <a href="">First link</a> <a href="">Second link</a>
</div>

Instead, use clickable padding on the anchors to create space between them:

<style>
  div.nav a { padding: 5px; }
</style>

<div class="nav">
  <a href="">First link</a><a href="">Second link</a>
</div>

Note how the anchors touch each other with no white space in the second example.

We do this in quite a few places in our apps and think it’s one of those small things that makes a big difference.

Think about paths instead of hierarchies »

I’ve been re-exposed to “industry” web design practices while staying with some friends in Germany who work at a large agency. In particular, I’ve seen that hierarchical navigation and site organization tactics are no distant memory. A lot of clients still come to the table with an org chart and ask their designer to implement the same structure on their website. The result is a website that reads like an office directory in the skyscraper lobby. Or the hierarchy approach can lead to terms that simply block customers from finding what they want. For example, my friend did some work for a shoe company who wished to hide six different kinds of shoes behind a gate called “Performance”. When my friend asked 40 uninvolved people in his office what the category “performance” meant to them, only 10 had even a vague idea. So hierarchies have their problems. What other organizing methods could we consider instead?

Instead of thinking in terms of hierarchy or up-front structure, I think it’s better to work with paths. A path is a line that goes from a starting point A to an accomplishment B. Each customer who comes to the site doesn’t care about the overall structure. They care about getting from A to B. That’s a path. Where are your golf shoes? That’s a path. Does my cell phone support international calling? That’s a path. Collect all the paths you can think of in a pile, pull out the 8 paths that 80% of your visitors come looking for, and that’s your home page. When paths overlap or the same customer needs them, weave them together. Add the occasional fork. DRY out paths with lots of overlapping information for efficiency. These operations feel concrete, and they connect directly with customer goals instead of organizational box drawings or hand-wavy concepts.

Lines are better than boxes for mapping the contours of your domain. So next time you work with a hierarchy-minded group, try to pull them out of the boxes and talk with them about individual starting points and goals for their customers.

Why do we plan up front? »

Buying my first place has been a really educational experience. I posted earlier about how I got boxed in with paint colors. Today I reflected on another lesson. When it comes to software development, I always try to follow a step-by-step approach. Mock something simple, see how it feels, decide what to do next. Rinse and repeat, and let the design unfold. It’s a slow game of patience and confidence, and I swear by it for the best results.

Why then, am I doing the exact opposite with our condo? We still haven’t closed, and I have a precision scaled floorplan in Illustrator full of furniture arrangements. I have a Backpack page detailing the exact sofa, sideboard, console, shelving, and landing strip gear. It’s a master plan with every piece fitting into the puzzle. And I haven’t the faintest idea if I’ll actually like it all.

I know I’m doing it all wrong. I should go to the real space and start with one thing. Pick the perfect sofa, put it in the living room, and feel it out. What is needed next? What would compliment the room now? What’s the next-most-important thing? My top-down plan is the total opposite of such a sensible bottom-up approach. So what’s going on here?

Here’s the secret: Uncertainty. It’s the same reason why so many people balk when we tell them to throw their functional spec out the window. I care so much about the design and feel and function of my condo-to-be that I can’t stand the uncertainty of not knowing how it will turn out. I want to know NOW so I can stop worrying about it. And of course, it’s impossible to really know what the best design will be without actually building the real thing step by step. But still, I don’t want to wait for such realities. And so I plan, and I plan, and I plan.

Plans are a strategy against uncertainty. The problem is, they only make you certain of your imagination. I’m lucky enough to know that my plan is a nervous occupation, not something I’ll follow. I haven’t purchased that sofa, that sideboard, or those shelves yet. And the next time someone furrows their brow when I tell them to slow down and go step by step, I’ll remember the feeling.

Perception, creativity and paint color »

Yesterday my wife and I stood in our unfinished condo deliberating paint colors. Closing day looms, and the developers require our color choices before they’ll finish their work. Our fondness for furniture aside, neither of us are interior designers or color mavens. So as we stood there in a white living room full of sawdust, we were stressing out big-time.

Fortunately one of our friends is an interior designer. We gave her a call and went back to the condo this evening. Within an hour, she took us from an intractable debate to a lovely solution. Given my line of work, I was as interested in her process as I was in the end result. How did she guide us to a beautiful color scheme when I, a supposed “designer,” couldn’t pick one color? What did she do differently?

The first thing she did is shed our preconceptions. “We can’t use a dark color in a small space” — not true. “We should have a different color in every room” — why’s that? “We don’t like [insert color]” — oh just give it a chance.

We had really boxed ourselves in with assumptions and myths, and I didn’t even realize it. She helped us forget these ideas and widen the space of possibilities. Next, instead of following abstract principles or assumptions, our designer looked closely at the colors that were already there. We looked at the colors of the cabinets, the dark wood floors, the surprising red touches in the light granite counters, and the green backsplash tiles. These were productive constraints, the kind you can juice. They reduced the possibility space in a way that was meaningful. Before long we had a palette of colors we loved, and a weight off our shoulders.

Creativity grows from constraints. But they need to be the right kind of constraints. The next time I think we “can’t” do something, I’ll try to remember my experience tonight and ask myself: Is this a meaningless preconception, or is it a productive fact I can work with? I know I’ll do better by focusing on the facts and leaving all other possibilities open.