You’re reading Signal v. Noise, a publication about the web by Basecamp since 1999. Happy !

Sam Stephenson

About Sam Stephenson

Programmer at Basecamp.


Iconography for meeting room layouts at Hotel Moskva in Belgrade.

Sam Stephenson on Aug 15 2012 6 comments

Announcing Pow 0.4.0 with support

Sam Stephenson
Sam Stephenson wrote this on 34 comments

We’ve just released version 0.4.0 of Pow, our zero-configuration web server for Rails development on OS X.

There are several new features in this release, including port proxying and better support for zsh users, but my favorite is a tiny addition that makes a huge difference when testing your apps on mobile devices.

Pow has always made it easy to access Rails apps on your computer with its built-in .dev domain. Just symlink your app into the ~/.pow directory and visit in your browser.

But what about testing your apps on mobile devices, or in IE? Pow’s .dev domain only works on your local machine.

Until now, testing on other computers required modifying /etc/hosts or setting up a custom DNS server on your router. Now we’ve fixed that, too.

Introducing, the magic domain name

Pow 0.4.0 has built-in support for, a free service from 37signals that provides wildcard DNS for any IP address.

With you can access your Rails apps from devices on your local network, like iPads, iPhones, Windows VMs, and other computers. No configuration required.

Say your development computer’s LAN IP address is With the new version of Pow, you can now access your app at And supports wildcard DNS, so any and all subdomains of resolve too.

Read more about at or check out the full source code on GitHub.

Installing and upgrading

See the full 0.4.0 release notes and install or upgrade with one simple command from your terminal:

curl | sh

As always, the user’s manual and annotated source code are available for your perusal.

Using event capturing to improve Basecamp page load times

Sam Stephenson
Sam Stephenson wrote this on 55 comments

We’ve been busy tightening the nuts and bolts on the all-new Basecamp in the wake of last week’s launch. As part of the process, I decided to take a closer look at client-side page load performance. Shaving even a tenth of a second off of page load time can have a big impact on perceived performance, so it’s a worthwhile investment.

Profiling the JavaScript page load event led to a surprising revelation. On pages with many to-dos, an overwhelming majority of the time was spent initializing sortable behavior. The culprit looked something like this:

$.ready(function() {
  $("article.todolist, section.todolists").sortable();

In other words, when you’d load any page with to-dos on it, Basecamp would make the items of each to-do list reorderable, then make the whole collection of to-do lists reorderable. That could take up to half a second on heavy pages.

Here’s the thing: you probably aren’t reordering to-dos every time you visit a project. It would be best if we could avoid initializing sortables until the last possible moment, just before you start to drag a to-do.

Deferring Initialization

That got me thinking. What would happen if we tried waiting until the first mouse press before initializing sortables? The mousedown event gets us a lot closer to the intention of reordering than the page load event. I tried it out:

$(document).on("mousedown", ".sortable_handle", function() {
  $("article.todolist, section.todolists").sortable();

The new code says that when we receive a mousedown event on the page that comes from somewhere inside a sortable drag handle, we should go ahead and initialize all the sortables on the page.

Sadly, this code doesn’t work. The sortable() initialization installs a mousedown handler of its own, but by that time it is too late. The event has already bubbled its way up to our delegated event handler.

If only there were a way to catch the mousedown event just before it begins its ascent up the DOM


CSS tip: Spot unsized images during development

Sam Stephenson
Sam Stephenson wrote this on 31 comments

Have you noticed that software feels cheap when UI elements move around on the screen without notice? Web applications are particularly vulnerable to this problem. Browsers give image elements a default size if they do not have explicit width and height attributes. Once these images have loaded, they expand or contract to their full size, causing all other elements on the page to reflow in response.

Unsized images reflow the page when they load

We try to avoid this in our applications, but it’s easy for an image tag to slip through the cracks. That single tag might be repeated many times in a loop, each instance causing the on-screen furniture to shift around in an unseemly way.

Here’s a tip for catching unsized images during development. Add this CSS rule somewhere in your stylesheet:

img:not([width]):not([height]) {
  border: 2px solid red !important;

Then any images without width and height attributes will be drawn with a red border so they’re easy to spot.

Device-scale user interface elements in iOS Mobile Safari

Sam Stephenson
Sam Stephenson wrote this on 20 comments

When we set out to build finger-friendly controls for iOS devices in Basecamp, two major constraints informed our design.

In Basecamp on a PC, when you hover over a to-do, milestone, or file, you’ll see edit and delete controls. But as has been covered here and elsewhere on the web, there’s no way to hover on a touch device. So our solution to this first constraint is to show the controls when you tap instead of when you hover.

The second constraint is that the controls must be finger-friendly. That is, they should be sized such that they’re always big enough to operate with a thumb, but never too big to fit on the screen.

Our first attempt at these controls turned out to be too small when zoomed out…

…and too big when zoomed in.


This shipping notification email from Waterfield succeeds at conveying a personal and sincere tone even though I suspect it’s automated. The subject invites you to open it and the “thanks for tracking us down…” paragraph feels genuine. (Nice subtle dig at the USPS’s “tracking” service, too.)

Sam Stephenson on May 27 2010 14 comments