Uber is pretty rad.
Sun, Aug 14, 2011I find the need to take cabs about once or twice a month. I've had a couple not-so-great experiences, but it's generally ok. Certainly nothing I particularly look forward to, though. Last night I splurged and got a ride from Uber, a new towncar service that just launched in Seattle. It ended up being about ten bucks more expensive than a cab, but it was a way better experience. They've done a really nice job of smoothing over a lot of the clunky or awkward aspects of normal car services.
First, I didn't have to call a dispatch, just a one-click "come get me" button on the Android app. I could then see details about the driver that was coming to pick me up. I could also see a map of how far away he was, so I knew right when he'd arrive. He knew my info too, so from the moment I walked out to the car we were on a first-name basis with each other (that's a tiny detail, but it was a nice feeling). The car was really nice and there was free bottled water waiting for us in the back seat. The driver was really friendly and explained to us that once we got to where we were going, we could review the route he took us on to make sure he wasn't trying to boost the fare by driving us the long way. Here's what it looked like:

It was pretty great. The quality of the experience was totally worth the extra cost. Would I use it over a taxi every time? Probably not, but it's nice to have another transportation option for those times when I want to fancy it up a little bit.
Smashvillians.com. A little project I've been working on.
Mon, Feb 07, 2011Lately there are a few things I haven't gotten to do quite as much as I'd like:
- Design
- Code with Ruby
- Go to hockey games
In an attempt to deal with all three at once, I've been messing around with building smashvillians.com, a fan-content aggregator for my favorite NHL team, The Nashville Predators. It gave me a chance to dig into Rails 3 (which I've learned that I really like). It's also a fun opportunity to play around, UX-wise, with content aggregation and curation. There's a few concepts in that area that I think are really interesting and I'm looking forward to doing some more stuff with. Also, I get to really nerd out about the Preds, and when I'm done actually have something to show for it.
Reflecting on recruiting.com
Mon, Sep 06, 2010Last Friday was my last day at Recruiting.com. Although I'm extremely excited about the new job I'm moving on to, I find myself looking back on the last four years with a lot of fondness. I figured I'd get all nostalgic and reflect for a bit. It was a fantastic experience that I've grown tremendously from.
I met the most awesome people:
So many amazing people have cycled through that place during my time there. My mind was constantly being blown by how much talent I was sitting right in the middle of. It was a fantastic learning experience. Whenever I talk to other people in the Seattle tech scene, they all bring up how many smart people that place churned out. Hopefully I don't bring the reputation down too much!
In addition to being smart and amazingly talented, a lot of them were just plain awesome. I have some amazing friendships with ex-Jobster's. One of them even introduced me to my girlfriend who I just got engaged to, so the whole experience was worth it just for that alone.
I learned what a start-up feels like, for better or worse:
Three weeks after Jobster hired me (and moved me out to Seattle from Boston) we laid off 70 people. That blew my mind, and made me wonder what I had gotten myself into. I saw scrambling business models, pressure from VCs, more layoffs, bad press, worse press, god-awful press, and a slow steady attrition by the survivors of layoffs.
I also saw people who believed so much in what they were doing and loved coming to work because of the impact they felt they could make. I saw a culture where it was expected that you'd question everything and challenge your assumptions constantly. It was somehow pulled off in a way where pretty much everyone grew from it. We learned what worked, and what didn't. More importantly, I learned that it was possible to do something about it when things weren't working. I had multiple "holy shit!" moments where we realized we had just stumbled onto something awesome in a way that no one else had thought of, and we could build things, and they'd solve people's problems in a real, meaningful way.
I built something I was proud of, and learned how to do it in a WAY I was proud of:
Things floundered for a while the first couple years that I was there, but in the last 18 months, we really nailed down a strong opinion about what we were there to do for people. We had a really clear objective and we stuck to it, even when it wasn't easy to do so. We had lots of really passionate arguments about whether this feature or that feature complimented or distracted from the core vision. We watched things that we built and felt really good about completely fail in user-studies, but we learned to do it quickly enough that it ended up becoming a good thing when it happened. I learned how to get deeper into the heads of people that I was trying to help (something that was particularly hard for me since I had never met a recruiter in my life before starting there). The deeper I got into it, the more exciting it became.
I learned that I really like doing this shit, after all
Building software is fun. I thought it would be at first, but I wasn't so sure about it during the first couple years out here. I thought maybe I had an idealized vision of it that was really far from reality. It sounded good on paper, but I got to thinking that maybe it's all just a lot of hard work that ultimately leaves you spending years on a single product that you weren't all that passionate about to begin with. I'm glad it all came full-circle. It could've EASILY ended up different.
Anyone who's at all familiar with the Jobster saga knows that a lot of craziness went down over the years. But now that it's all behind me, none of that stuff really matters. It makes for some amusing memories, but what's really important to me is that I got to work with awesome people, build something awesome, and do it in a way that I feel really good about. I even made a few recruiters' lives a teeny bit better in the process. :) I have a much better sense of myself and what I find fulfilling as a result of it, and I can't wait to take the things I've learned to the next level.
Successful infographic: World Cup matches by Michael Deal
Tue, Jul 06, 2010I feel like there are WAY too many infographics that fall down because they pack way too much data into the presentation. The ones that succeed tend to pick a single data-point (or a very small set of related data points), and use it to illustrate a single concept. It's so tempting to try to show off everything you learned from the data-set, but it can also get overwhelming, really quick. It's an easy trap to fall into, especially for the infographic designer that probably enjoys getting completely lost in data.
Over the weekend, I came across this visualization by designer Michael Deal, which I think is fantastic. He explores the matches in the World Cup by visualizing passes, shots on goal, and goals scored across an entire game. It's a lot of information, but it's insanely digestible. I'm an utter noob when it comes to soccer, and I'm kind of frustrated that I don't have my head wrapped around the game enough to enjoy watching it. But by spending just a couple minutes with this visualization, I can see a picture of the games that not only makes sense to me, it makes me want to learn more.
For example: (click the images for the full infographic)

This must have been a really frustrating game for Spain. They dominated on passes and shots for the entire game, but Switzerland ended up taking the match.

This shows how Italy was dominant in the game in a way that the 1-1 tie doesn't illustrate.
Michael has some other awesome infographics on his site.
Tony Hsieh from Zappos has SPIES EVERYWHERE!!!
Fri, Jul 02, 2010Ok, maybe they're not spies, maybe he has an army of fantastic little elves, or ninjas. happiness ninjas. Regardless of how he did it, Tony from @zappos made my day yesterday, in a way that completely fits into his personal narrative of 'Delivering Happiness'. The thing is, there's no way he could have possibly done it on purpose.
I'll explain:
I'm currently right in the middle of trying to make some pretty heavy life-decisions. I'm at a bit of a crossroads, both personally and professionally, and I'm trying to figure out what's next.
- Do I move, or stay in Seattle?
- What kind of work situation would I enjoy the most?
- Do I take some time off work, or do I dive right in to something new? (there's a fair bit of opportunity out there for UX designers at the moment)
- What kinds of changes will make me the happiest? How do I start to figure out what that even means?
So many questions! I was a kinda frozen, with no clue where to start, and it was really starting to stress me out.
So bad, in fact, that I ended up with a migraine yesterday. The way my migraines work, the headache is annoying, but it's not that bad. The part that really gets me is that I go FREAKIN' BLIND for about 30-45 minutes. Then I get my sight back and I have a kinda nasty headache for the rest of the day. (Silver lining, It's a fantastic way of making me take a break from whatever I'm doing that's stressed me out in the first place.)
Anyways, I bailed out of work early to go sleep it off. I half-blindedly stumbled home, and as I'm walking in the front-door, I literally trip over a copy of Tony Hsieh's book, Delivering Happiness. I had requested a copy 2 months ago in response to this tweet, and kinda felt bad about it afterwords, because I figured I probably wasn't going to like it that much. If he's gonna be giving them away to anyone, it should probably be to people that are psyched about it. See, I'm not a big fan of "business-y" books. I find the vast majority of them to be fairly smarmy. But, I had seen Tony Hsieh speak at SXSW a couple years ago, and he was pretty entertaining. Plus, when I saw that tweet, it was a really slow day at work, and what else was I gonna do?
It ended up being the best possible timing for a book delivery in history.
It's pretty hilarious that a book about happiness in the professional context shows up on my door at the exact moment that I'm thinking about it so much that it's making my brain hurt. I figured I could use something to take my mind off things, I started flipping through it. I figured it's the least I could do for a guy who sent me a copy of his book that I didn't pay for, and only sorta, half-heartedly, asked for.
Fast forward 24 hours later, and I've read it cover-to-cover.
Well, mostly. I ended up skimming a little bit in the middle. (Sorry, Tony. There's only so much of a big company's core-values document that I can take at 1am, given my general aversion to big companies.) But it was pretty good, as far as those type of books go. I feel like way too many business / personal development books are written from a slant of "follow your passion and profit Profit PROFIT!!!", and that just feels sorta gross to me. Delivering Happiness, on the other hand, seems to come from a much more personal place. Tony Hsieh seems like a guy who, while obviously very financially-successful, is more psyched because he learned along the way that there are, in fact, much more meaningful things than money, and he just wants to share.
Also, I really appreciate that he spends two pages breaking down his loving relationship with Red Bull, and that he thinks pickles make him happy because "they are obviously delicious and I enjoy saying 'Pickles'."
I'll spare the book report, other than to say I got a lot out of it. You should check it out, if that sort of thing sounds at all interesting to you. The main point of this post is that it was EXACTLY what I needed at that point in time. I totally got lost in it, and that got my mind off all the hemming and hawing I was doing that wasn't helping anyway. It also gave me some nuggets to think about that help put some stuff in perspective. And, dude is just a pretty good storyteller. You can tell he's stoked to be talking about the stuff that he does (something I noticed when I saw him at the SXSW 09 keynote, too).
So, Tony, however you did it, be it by pure serendipity (most likely what happened), or some skynet-esque computer that monitors the entire world's tweets and foursquare checkins (what I'd like to think happened), you nailed the timing on that one.
Good job, sir.
Man vs. Food: A ridiculous visualization for a ridiculous tv show
Fri, Jun 18, 2010Here's another HTML5 exploration. This time, it's the Travel Channel show Man vs. Food.
I shouldn't like this show as much as I do, but I can't help it.
Here's the data-driven look at the first two seasons, click the image for the full infographic. (Sorry IE users, this one is Firefox / Chrome / Safari only)
Commands in TextMate are awesome.
Thu, Jun 17, 2010I've used Textmate to write code for the past year or so. I always thought it was a fantastic editor, but I stumbled on something new (to me) about it the other day that makes me like it 1000 times more. You can write commands to automate tedious tasks in Textmate, and you can do it in just about ANY language that you already know. For me, that's Ruby. Writing commands with it is super easy.
Lately, as I've been doing more CSS3 stuff, I've gotten more and more frustrated by having to type all the browser-specific extensions for properties that haven't been quite finalized yet. It's annoying, and I'll inevitably start leaving stuff out because I don't want to mess with it (Sorry, Opera). But once I figured out that I could write commands in Ruby, I was able to whip this up in just a couple minutes:
#!/usr/bin/env ruby
s = STDIN.read
s.gsub!(/([[:blank:]]*)border-radius: (\d+px);/) do
"#{$1}border-radius: #{$2};\n#{$1}-moz-border-radius: #{$2};\n#{$1}-webkit-border-radius: #{$2};\n"
end
s.gsub!(/([[:blank:]]*)box-shadow: (\d.+);/) do
"#{$1}box-shadow: #{$2};\n#{$1}-webkit-box-shadow: #{$2};\n#{$1}-moz-box-shadow: #{$2};\n"
end
s.gsub!(/([[:blank:]]*)transition: (\S.+);/) do
"#{$1}transition: #{$2};\n#{$1}-webkit-transition: #{$2};\n#{$1}-moz-transition: #{$2};\n#{$1}-o-transition: #{$2};\n"
end
print s
Then I saved it as a command (Menu > Bundles > Bundle Editor > Edit Commands), and set the input to "Selected Text" or "Line", so I wouldn't accidentally run the command over and over again on different parts of the document.
It's nothing crazy, but it makes my day WAY easier. Now I can just type the non-browser-specific CSS declarations, then run the command (from the Bundles menu), and all the CSS declarations I've selected get expanded out to their browser-specific versions. For example:
#foo {
border-radius: 5px;
box-shadow: 2px 2px 4px #ccc;
transition: width 0.3s linear;
}
becomes:
#foo {
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
box-shadow: 2px 2px 4px #ccc;
-webkit-box-shadow: 2px 2px 4px #ccc;
-moz-box-shadow: 2px 2px 4px #ccc;
transition: width 0.3s linear;
-webkit-transition: width 0.3s linear;
-moz-transition: width 0.3s linear;
-o-transition: width 0.3s linear;
}
It's pretty rad. I wish I had known about that earlier. I'll probably expand on it as needed, but these three rules are already saving me a lot of time. For example, figuring out an easy way to do CSS gradients would be cool, but seems like it'd be an really ugly regular expression.
Visualizing Lord Stanley's Cup: an HTML5 experiment.
Sat, Jun 05, 2010 
Here's a little something I whipped up over the past week. It's an interactive visualization of the winners and losers of the Stanley Cup finals since 1927. I was trying to accomplish two things: 1. learn how to use some new stuff in HTML5 (canvas, css transistions, etc), and 2. teach myself a little bit about hockey. I'm pretty psyched at how it turned out.
By the way, Internet Explorer completely barfs on this, so it's really only worth looking at if you're using Chrome, Safari, or Firefox.
How I did it
1. Start with simple HTML markup.
It seemed like the right way to start was to put all the data into something simple that would display fine on it's own, in any browser, then transform it into something more interesting with javascript and css. I came up with a simple HTML structure that showed the wins and losses for each team, and allowed for some notes for context.
<section id="sc-timeline">
<ul id="timeline-data">
<li id="calgary">
<h3 class="team-name">Calgary Flames</h3>
<div class="timeline">
<h4>Stanley Cup Wins:</h4>
<span class="win" title="1989/05/30">1989</span>,
<h4>Stanley Cup Losses:</h4>
<span class="lose" title="1986/05/30">1986</span>,
<span class="lose" title="2004/05/30">2004</span>
<h4>Notes:</h4>
<span class="note" title="1972/10/01">Founded in 1972</span>
</div>
</li>
</ul>
</section>
... then repeat the list-items for each team in the data set.
2. Build a timeline with Javascript.
Now that the raw data is on the page, I need to add some stuff to it so it will actually be interesting. I stored all the javascript to control the visualization in an class called 'timeline'
var timeline = function() {
this.init = function(el) { ... setup stuff goes here ... }
... more logic goes here ...
}
Then I created an instance of the class, and run an initialize function that adds in the extra HTML we need for the visualization.
var sc_timeline = new timeline();
sc_timeline.init($('SECTION#sc-timeline'));
Rather than paste in all the code here, which would be overwhelming, have a look at the source.
In the init function, three bits of extra markup are added to the existing html, so the structure now looks like this:
<section style="width: 1010px;">
<ul id="timeline-data">
<li>...</li>
</ul>
<!-- this stuff below is added by the timeline.init() function. -->
<canvas class="timeline-canvas" height="270" width="1010">
<ul class="timeline-bar">
<li>1927</li>
<li>1928</li>
... etc.
</ul>
<div class="timeline-titles"></div>
<div class="timeline-notes"></div>
<section>
All of that is super easy with jQuery.
3. Add some CSS
Now, all the markup is there, but it's pretty ugly. In a CSS file, I floated all the list items so they displayed horizontally, hid the raw data (wins, losses, notes), positioned the new timeline-title and timeline-notes DIVs on top of the CANVAS element, and added team logos to each LI in the timeline-data list (using the team_logo_nav.jpg sprite)
It's all really straightforward CSS, but there's one thing I want to point out. When you hover over the team logo, I used a CSS transition to give some animation to the background position. It's the first time I've ever used that, and I like it a lot. I can imagine some really cool stuff that can be done with it. (too bad it only works in Safari and Chrome, currently)
-webkit-transition: background-position 0.3s linear;
4. Add interactivity
There are two bits of interactivity I want on this thing. First, you should be able to mouse over the team logos and display the years they were in the finals, along with any notes. Second, and inversely, you should be able to mouse over the years in the timeline and see which teams played on any given year.
In the timeline setup, I attach the actions to the list items:
this.setup_timeline_actions = function() {
public_instance = this.public_instance; // this is a reference to this instance that we can attach to HTML elements that need to refer back to it.
this.teams.find('LI').hover(function() {
public_instance.draw_timeline_links(this);
});
this.years.find('LI').hover(function() {
public_instance.draw_matchup(this);
});
}
I won't go through the ins and outs of how I did the highlighting of the corresponding list items. It's basically finding the matching years or teams by filtering the list for an ID or title attribute, then adding a 'selected' class to them and writing the team name to the timeline-titles DIV element.
Oh, and then I got to the fun part...
5. Drawing with CANVAS.
I think the most interesting part of the visualization is the bars that link the teams to their win or loss years. I did it with the HTML5 CANVAS element, which is basically a scriptable image tag that you draw on programmatically. It's not difficult, but it's way different than basic DOM scripting like I'm used to.
To make it work the way I wanted, I sized the canvas to be exactly as wide as the list items. Then I could easily to draw links between the two rows, just by finding how far the corresponding elements were from the left edge.
this.draw_connection = function(team,year,color) {
// this.ctx() is a reference to the context object of the canvas.
this.ctx().globalAlpha = 0.2;
this.ctx().fillStyle = color;
// get the coordinates
var l1 = team.position().left;
var l2 = year.position().left
var r1 = l1 + team.width();
var r2 = year.width() + year.position().left;
var h = $(this.stage.canvas).height();
// draw the connection
this.ctx().beginPath();
this.ctx().moveTo(l1,0);
this.ctx().lineTo(r1,0);
this.ctx().lineTo(r2,h);
this.ctx().lineTo(l2,h);
this.ctx().fill();
}
When I loop through all the teams and draw their connections, with blue bars for wins, and red bars for losses, it creates a pretty neat effect:

Drawing notes is pretty simlar, I drew a line on the canvas, then positioned the note text on top of it, left-aligned to the line:
var year_pos = this.stage.years.find('LI#y' + year).position().left;
var h = $(this.stage.canvas).height();
this.ctx().strokeStyle = '#00ff00';
this.ctx().globalAlpha = 1;
this.ctx().beginPath();
this.ctx().moveTo(year_pos, 0);
this.ctx().lineTo(year_pos,h);
this.ctx().stroke();
this.stage.notes.append(''+ note.note + '');
Creating a note layout that looks like:

From there, it's just a matter of clearing the canvas whenever a year or team is hovered, then drawing the connections all over again, but just with the selected year.
Again, here's the finished product. View the source to see the details of the javascript.
Learn more about working with the CANVAS tag.
Learn more about CSS transitions.
Update: The guys at FanSnap had me build a timeline for the NBA finals. I made some design refinements with this one and made it work in IE. By "made it work in IE", I mean "made myself feel really dirty while making it look only halfway-passable in IE".
Infographic: Epic US Floods in the last 100 years, Damages and Casualties
Fri, May 21, 2010I've been thinking about floods a lot lately. A few weeks ago my hometown, Nashville, TN was hit with the worst flooding it's had in at least 80 years. Seeing all the images of the damage was pretty mind-blowing. I'm still having a hard time wrapping my head around the extent of it all.
To make at least a little sense of it, I started diving into as much of the raw data as I could find. In the process, I realized a sad truth about floods. It's really easy to underestimate how big of a deal they are, provided they don't happen near to a place you have a particular attachment to. In the past decade, there have been a few floods that were at least as destructive as the Tennessee floods, but I don't really remember them. Or, I do remember them, but didn't think they were that big of a deal. Just a whole lot of rain. Add that to the fact that the Tennessee floods went down on a weekend where there was an environmental crisis, and a failed terrorist attack in NYC, and it's easy to see how the severity of the situation was lost on a lot of people outside of the South.
Here's an infographic I pulled together exploring the damages and lives lost in several of the largest floods over the past 100 years. Click through for a larger version.
And please, if you're feeling at all generous, there's a lot of folks in Nashville that could use a hand. Consider making a donation, buying something, or if you're in the area, take a little time to help out. Thanks.
(sorta) Practical CSS sprites for high-traffic sites:
Sun, May 09, 2010This past week, I learned about how google is starting to take server speed into account in their search result rankings.
It reminded me of some work I did a year or so ago when I was a front-end developer for Jobster.com. We were getting just shy of a million unique visitors / month at the time, and our servers were starting to strain under the load. We solved some pretty big performance problems by reducing 50+ image requests on each page to just 2 using CSS sprites. Here's some of the stuff I learned during that process.
First off, look at these two pages, for a fictitious online candy retailer called BaddassSnacks! They should look identical. The only differences are under the hood. I noted some details about the assets used in each page.
Demo #1 |
Demo #2 |
|
Total image files: 24 |
Total image files: 1 |
Getting all of these images to work with a single CSS sprite was a bit of a challenge. Here's a few of the techniques I used to make it all work:
1. Replacing a block of text with an image:
This is one of the most straightforward things to do with CSS sprites. Just make sure the text is contained in a block-level element and set the height and width of the element to the same as the image. Of course, you'll need to hide the text too, here's how to do it.
/* page logo, for example */
H1#logo A {
display: block;
height: 100px;
width: 175px;
text-indent: -9000px;
outline: none;
/* set the background to your sprite, then move the sprite into position
in this case, 25px from the left and 50px from the top */
background: url(/path/to/your/sprite) -25px -50px no-repeat;
}
This can turn into a lot of CSS if you're doing this with a lot of images. You can clean this up a bit by creating a single class that you can apply to any text-containing element that you want to turn into an image. I usually call this class ".img" or something similar.
.img {
display: block;
text-indent: -9000px;
outline: none;
background: url(/path/to/your/sprite);
background-repeat: no-repeat;
}
H1#logo A.img {
height: 100px;
width: 175px;
background-position: -25px -50px;
}
here's an example from the demo page:
![]()
2. long, tiling backgrounds
If you need an image to tile horizontally AND vertically, you're out of luck when it comes to sprites.
But if you can live with only tiling images horizontally, then you just make a REALLY tall sprite with all your horizontally-tiling images, then use background-position to line them up to the right point.
Again, an example:
![]()
3. Backgrounds for elements with a variable width
This is really similar to #2
You can use the sliding doors technique with CSS sprites, you just need to make sure that your sprite is as wide as your widest variable-width element is likely to be.
![]()
4. Bullet icons
This is where things start to get a little bit tricky when you're using sprites, and it's difficult to come up with something that's bulletproof. The problem is, in a nutshell, that you want to make use of individual icons, but because they're on the sprite, the neighbors of the image you want will show through unless you've positioned them just so. In this example, I just made the image really tall and gave everything a lot of padding. I've found that increasing the dimensions of the image doesn't increase the file size proportionally, so you can get away with it and still achieve a smaller total file size.
![]()
5. Inline images
These seem tricky, but are actually quite easy, so long as you're willing to put up with one teeny bit of ugliness in your code. The obvious problem is that inline elements can't reliably get a height and a width in all browsers. You need something that will act like an IMG element. As it turns out, that's what you use. But, we want to keep our images all in the sprite, so how do we do it? There are two ways. First, and easiest, accept the extra server hit and serve your inline images as a 1x1px transparent gif.
<img src="/images/invisible.gif" />
Then use css to set the height and width of the image and use your sprite the same way as you would with any block-level element. That's what we did on Jobster.com, and it worked fine. The second way is uglier, but will keep you from using a second image. The SRC attribute of the IMG tag usually takes a url to an image file, but you can also put raw image data in there. This will give you an image that's the equivalent of the 1x1px transparent gif:
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" />
Did I mention it's ugly? In either case, you can then use CSS to position the sprite like so:
IMG#whatever_id_you_give_to_the_inline_image {
height: 15px;
width: 45px;
background: url(/path/to/your/css/sprite) no-repeat -50px -65px
}
![]()
And that's basically it. For a real-world example of most of these techniques, check out the search results pages on Jobster.com (although I don't work on that site anymore so no guarantees that things haven't changed in the meantime)
One bad design decision can ruin an otherwise good experience.
Sun, May 09, 2010The other day I tried out Threadsy, an email and social-stream aggregator. I was immediately impressed. It's really nice to not have to go to 4 different places to keep up with all your emails / notifications / direct messages / etc.
After I had been using it for a little bit, I got this pop-up:

I actually was really liking it, and was already thinking about Tweeting about it, so I thought "oh sweet, they just made that part easier for me as well". I clicked the button. It spun for a second, then gave me a thanks message. I thought to myself, "Thanks? Wait, what? That's not what I expected!? When do I get to share how stoked I am about this app?"
Hoping I was wrong about what just happened, I opened up Twitter and sure enough:

Which I immediately felt compelled to follow up with:

Now, it's pretty easy to argue that it's my fault for not guessing that would happen, but that still leaves a horrible taste in my mouth. I wanted to tell people that I thought there was a cool app they should check out. I definitely didn't want to tell them about some spammy-sounding t-shirt contest, nor, more importantly, did I have any indication that I was about to. The first I had heard about a contest was by reading the tweet I just posted. It's annoying for any app to do that, but it's extra-ridiculous when it's an app that wants to manage my social streams. It's a pretty negative blow to the trust I have in them.
That's a bummer, because aside from that, it looks really cool. One small design decision pretty much ruined the good experience I was having with that app.
To be totally fair to them, they did respond to my tweet really quickly, saying they were sorry and that they were removing the preview-less share pop-up. And honestly, this isn't the most egregious breach-of-trust I can think of. But it really does illustrate the point that first-user-experiences can be tricky and designers should take just as much care with them as they do with the rest of the app.
There's no wrong way to eat dessert...
Sun, May 09, 2010A few months ago, I wrote a clunky blog post about my thoughts on user-experience design as participatory storytelling. It felt pretty corny, and I don't think it fully got across the core of what I was trying to say. Today, I saw an article in The Stranger about Dana Cree, the pastry chef at Poppy, here in Seattle. She's insanely talented at what she does (I've eaten there, the desserts are ridiculously good). The whole article is great, but at the end there's a quote that I think is a pretty eloquent illustration of what I was trying to get at when I said user-experience design is about setting the stage for a person to create their own personal story.
...Then I ask her, considering all the love and purposefulness that goes into creating each platter, if there is a specific way to eat Poppy's dessert thali to get the most out of it.
"No, there's never a wrong way to eat it," she exclaims with a smile. "The human element is fascinating. I can send the same dessert to five different people, and it will become five different desserts. My goal is that it tastes like the best version of what you expect."
In this case, she just happens to be talking about wonderful, wonderful desserts instead of software design. :) read the rest at thestranger.com
Two simple CSS rules to make print-outs of your site WAY more readable and usable
Thu, Apr 22, 2010Today, I was doing a little bit of work on the design of the new marketing site for my employer, and I heard from the sales team was that print-outs of the home page looked really broken. I took a look, and they were right. It was mainly due to the fact that I had used CSS background replacement to swap out the text in the header tags for graphical text. That's a good trick for keeping clean markup, but since printers generally don't print background images, it basically creates huge gaping holes all over the page.
I fixed it, in a fairly reusable way, by moving the css that hides the html text into an @screen only declaration, then using an @print declaration to undo any height and width that may have been set, so the text in the image will flow as normally as possible.
/* Hide text for background replacement */
@media screen {
.img {
display: block;
text-indent: -9000px;
outline: none;
}
}
@media print {
/* remove the dimensions on .img elements so the text in them will flow more naturally */
.img {
height: auto;
width: auto;
}
}
Then any elements I wanted to do background-replacement on would get the .img class applied to them, along with a separate declaration defining the height, width and the background image. For example:
<h1 class="img" style="height: 100px; width: 175px; background: url(/company-logo.jpg) 0 0 no-repeat;">My company, inc!</h1>
That solved the issue pretty well. While I was looking at it, however, I realized there's something else that bugged me. Anchor text on a printed page is totally useless. It would be nice if I could include the URL along with certain links on the printed page.
Luckily, with a tiny bit o' CSS, I can.
@media print {
/* make links more useful when they're printed. */
.print-url:after {
/* NOTE, replace INSERT_YOUR_SITE_NAME_HERE with your domain name */
content: " at http://INSERT_YOUR_SITE_NAME_HERE" attr(href);
}
}
Then, in your HTML markup, you can add the class .print-url to any link that you feel the url should be displayed on the printed version. Something like:
<a href="http://foobar.com/get-a-demonstration" class="print-url">Get a demonstration</a>
gets printed as:
Get a demonstration at http://foobar.com/get-a-demonstration
It's nothing crazy, just two simple tweaks, the .img should work pretty much everywhere, and the .print-url rule will work everywhere except for IE6/7, in which case users will just see the anchor text.
Here's what the printed homepage looked like before (here's how it looks in the browser, for reference):

...and here it is after. (with these two rules and a little bit more print-specific CSS cleanup):

Just one of those little things that's helpful, and so easy that there's really no reason not to do it.
Getting data for a visualization design with Nokogiri, mysql, and R
Mon, Nov 30, 2009I recently did some analysis of my Last.fm listening history to figure out what my ideal rainy fall mix would be (see final list here). It was fun, and I learned a couple cool things in the process.
Step one, Get the data:
First things first, I needed to get a list of all the songs I've ever scrobbled on Last.fm, and some historical weather data to mash it up with.
Last.fm gives you some fantastic data feeds, but there's no way to export your entire listening history. And for all the weather sites out there, I couldn't track down a single one that would give you historical data in a structured format (like JSON or even CSV).
However, both Last.fm and Weather Underground had an HTML interface for browsing the data I wanted, page-by-page, in small pieces.
The thought of writing a scraper for these sites seemed pretty daunting, but it actually turned out to be REALLY easy. Using this post as a guide, I wrote a couple of small Ruby scripts using Nokogiri and FasterCSV to scrape the pages and save the relevant data to a .csv file.
disclaimer: this code isn't pretty, by any means, but it was easy and it worked.
See the scraper for Weather Underground
Once I had those written, I could just do this in an IRB sesion:
> require 'LastFM' > require 'WeatherData' > LastFM.get_tracks > WeatherData.get_weather
All in all, it took me about 45 minutes to wrap my head around Nokogiri and hack together something that got the data I wanted from both sites. Not too bad. Way easier than I expected it to be, anyway.
STEP TWO: Get rid of the sunny good-weather stuff
Now, I needed to filter it, so I dumped both csv files into mysql and ran this query. I think it's pretty self explanatory:
SELECT s.artist, s.song, w.conditions FROM songs s JOIN weather w ON w.date = s.date WHERE w.conditions IN('Rain','Partly Cloudy','Scattered Clouds','Snow','Overcast','Fog','Mostly Cloudy') AND MONTH(s.date) IN(9,10,11,12)')Now, I've got over 9,000 songs that I listened to between September and December, when it was overcast, raining, or snowing.
STEP THREE: Visualize
I could've done all the analysis with mysql queries, but I know this will probably turn into some sort of visual exploration on the mixtape jacket design, so I exported the results to a CSV and brought them into R.
From there, it was pretty easy to get to what I wanted, the top artists I listed to on rainy days.
fall_song_data = read.table('~/fall-rainy-songs.csv', header= TRUE, sep="\t")
fall_artist_counts <- table(fall_song_data$artist)
pie(fall_artist_counts[1:30])
Not super pretty at this point, but interesting. Also, relieving. I can actually make, in my opinion, a pretty damn good fall mix out of these bands.
There were all sorts of other neat facts I was able to pull out of this data, but this gives a general idea at how easy it was to get the data and do something with it.
My perfect mix for a rainy fall day (statistically speaking)
Mon, Nov 30, 2009
The November theme for Rain City Mix Tape Club is Rainy fall jams. It's a good theme, there's lots of songs that just scream out to be listened to on an overcast fall day (especially here in the northwest).
I thought it might be neat to take a more data-driven approach to this mix than usual. I have 3+ years of my music listening data on Last.fm, so I *should* be able to say, quantitatively, what my ultimate rainy fall jams are, based on what I was actually listening to, on rainy days in the fall. The really interesting bit would be whether or not that matched up at all with what I would subjectively choose to put on a rainy fall jams mix.
For a nerdy technical breakdown of how I did it, check out this post.
I was originally just going to take the 15 songs that I listened to the most on overcast or rainy days between September and December. As it turns out, 9 of them were by the same band, because I tend to get obsessive about certain albums.
So instead, I decided the best way to represent the data in a single mix, while still giving it some variety, was to take the most listened-to song by each of the 15 bands I listened to the most during Autumn, under those weather conditions. There were a couple surprises, but for the most part I'm pretty pleased that it actually turned into a fairly listenable mix.
Here's how it ended up:
I tried to link directly to the song, where possible. Last.fm didn't have a streaming version of all of them, though.
-
Yo, Get Into It, by Latterman
I wouldn't have guessed this would be my top song on rainy fall days. But it turns out, during cold, rainy weather, I listen to this band way more than anything else. I guess bleak fall days call for an anthemic pop-punk pick-me-up.
-
Radio, by Alkaline Trio
This one makes a lot more sense. I'm not a big fan of fall so it makes sense that bleak, depressing songs with a healthy sprinkling of "go f**k yourself" seem just about perfect.
-
Cry of the Black Birds, by Amon Amarth
Thor FTW! If I were a viking, I'd do most of my pillaging and plundering between Labor Day and Christmas.
-
Across the Shields by Torche
Poppy metal is a great counterpoint to weeks of non-stop drizzle.
-
Better Half, by Jawbreaker
I was a little surprised that this song scored this high, but Jawbreaker was one of my favorite bands in High School, and cold autumn days make me nostalgic, so I guess it makes sense.
-
Thousand Scars by Envy
I can see Elliot Bay from my office window, and this song + the rain + the cargo ships sailing past = awesome. I can't really explain it. There's just something about it all that looks / sounds rad.
-
Rodeo Clown, by Lifetime
Not an obvious fall song, but I listen to this band a lot year-round. Chances are, it would also be on my Winter, Spring and Summer jams mixes, too.
-
We're so Small, by The Epoxies
Another one filed under "poppy new wave antidote for gloomy weather."
-
Flights End, by Burst
Honestly, I don't even like this band that much. I have no clue how they ended up ranking so high. I guess I just subconsciously gravitate towards Swedish metal bands in the fall?
-
Shadows, by Sinking Ships
I can't really put my finger on it, but something about this song seems totally appropriate for this mix, even though it's not terribly obvious.
-
Spit Shine Your Black Clouds, by The Blood Brothers
The darkness and weirdness of this song (this whole album, actually) makes a great compliment to those days when you're going just a tad bit crazy because you haven't seen the sun in weeks.
-
On the Nod, by Avail
Like the Lifetime song above, this one is on here because I listened to this band all. the. damn. time.
-
Train Wreck Love, by Stabbed By Words
This one was a complete surprise. I think this song is pretty stupid, actually. But, it's catchy. The rest of this album is much better.
-
Chips Ahoy!, by The Hold Steady
Sometimes you need to feel happy, that's what The Hold Steady is for.
-
David Comes to Life, by Fucked Up
This band reminds me that however insane I get while cooped up in the rain all winter, there's a fat, hairy, mostly naked Canadian man who's much, much worse.



