Archive for the ‘Trello’ Category

Announcing The Fog Creek Fellowship

July 21st, 2014 by Elizabeth Hall

The tech industry has a problem and Fog Creek shares it. Our small thirty-nine person company has eleven developers — all of them male — and only 14% of the technical applicants we have spoken to in the last six months have been women. We have extremely talented women working in various roles such as quality assurance, scrum master, finance, recruiting, and office management but no developers. We’re proud to have had (and currently have) truly amazing female developer interns. Their contributions to the team and company at large are apparent, but alas, we have none working with us full-time.

Everyone here at Fog Creek wants to help reverse this gender disparity. In the past, we’ve focused on our intern pipeline by recruiting heavily from schools with high percentages of female students. We’ve hosted and sponsored hackathons and events with a focus on women in tech. We provide continuing education programs for female employees who want to learn how to code. These efforts have helped some, but it’s not enough.

We want to do more. We need to do more. We will do more.

As part of a larger solution we’ve joined forces with our neighbor, The Flatiron School to create The Fog Creek Fellowship. The Flatiron School has an unprecedented commitment to diversity, training women and underrepresented groups through partnerships with government and self-funded scholarships. Their highly selective admissions process, their focus on incredible teachers and great curriculum, and their dedication to the programming community, have led to an exceptional track record of helping alumni launch programming careers with great companies. Their passion for providing women the skills they need to succeed in tech is contagious — making them the obvious choice for our partnership.

Fog Creek wants to keep The Flatiron School’s positive momentum going. A select group of female Flatiron School graduates will join us for a two month program where they’ll be paired with a Fog Creek or Trello mentor. The program kicks off with brainstorming breakfast where fellows arrive with three project ideas. Once they flesh out the details with their mentors they’ll begin working right away. Throughout the program they’ll also undergo technical interview training from our developers.

Fellows will experience what it’s like to work at a company that values developers. They’ll each have access to their own height adjustable desk, Aeron chair and all the snacks one can imagine.

Fellows will receive interview training from their mentors and be provided with immediate technical feedback, which is extremely rare in an interview setting. Our developers undergo months-long recruiting training and have conducted hundreds of coding phone and in-person interviews. They have priceless information to share with our fellows.

Fog Creek values the camaraderie and closeness that eating lunch together provides. Every day, fellows will either join the Fog Creek and Trello employees for a catered lunch or have a special 1:1 lunch with their mentors. Participating in these conversations, or just listening in, is a great way to dive into the tech community and continue learning.

Additionally, all fellows will have 1:1 pair programming sessions with their mentors. Fog Creek currently has a 0.4% acceptance rate for full-time developers; The fellows will be working with the best in the industry.

The Fog Creek Fellowship provides women, who have just learned a new skill-set and are eager to start their career in tech, the tools they need to get their first programing job. If we can help fellows prepare for coding interviews, offer assistance comparing offer packages, build confidence, and help create a long-lasting professional relationships with their mentors then we’ve done our job. We want to be a resource long past the program’s end date.

We are beyond excited to start this new endeavor and we hope it brings change to not just Fog Creek but to the tech community at large.

The Fog Creek Fellowship is only the beginning though; we know we have more to do. We are currently working with other amazing organizations in the industry to help all underrepresented groups in tech. Future exciting announcements to come!

* * *

Do you know of other organizations, schools, or people advocating for underrepresented groups in tech? I’d love to learn more, tell me about them!

Eight Jackalopes Walk Into An Office

July 9th, 2014 by Elizabeth Hall

Intern Group Final

As always, our interns are working on real features for our real products and have already made tremendous contributions to the Trello and FogBugz teams. We think they’re pretty special – not only did they stand out amongst the 776 applications we received but during these first few weeks they’ve had the chance to teach us a thing or two. Whether it’s coming up with new strategies for dealing with the Tanner during Werewolf or showing off cool video games they’ve made at hackathons, the class of 2014 is constantly impressing us.

Before we blink and it’s all over we want to take a moment to show off this year’s amazing talent. Here they are our eight wonderful interns (lovingly dubbed jackalopes*) in their own words.

Alex Lew

Hi! My name’s Alex, and I’m an intern on the Platform team this summer. Obligatory fun fact: I grew up in North Carolina, and my high school’s library had the largest collection of books and music in and about Esperanto of any library in the United States (excepting the Library of Congress).

Laura Watiker

My name’s Laura and I’m working on the Trello team this summer. During the school year, I go to Oberlin College in Ohio, studying CS and Econ. I grew up in the New York City suburbs, but I’m happily living in the Brooklyn housing this summer. Aside from pushing lots of computer keys, I do work with Oberlin’s co-ops, play a bunch of instruments, and theorize 2048 strategy.

Graham Carling

My name is Graham, I just finished my Sophomore year at Brown. I am originally from Manhattan and a graduate of Stuyvesant high school, a short walk from the Fog Creek offices. I am majoring in Computer Science (I know, shocking) and for the last couple semesters I have been working as a TA for some of Brown’s CS classes. Outside of work I like going to concerts, mainly of the electronic variety, along with seeing my friends from high school and working on a side project of mine. So far my summer has been packed full of fun events, and when I’m not going fishing or shooting arrows I’ve been working on the new notification center feature for FogBugz.

Jonathan Pevarnek
Hello, I’m Jonathan, a masters student in Computer Science at the University of Michigan. I’m from a small island called Grosse Ile in south-east Michigan. When I’m not working, I like to read books, go on bike rides, and work with a campus community service organization (Circle K). This summer, I’ve mainly been working with Doug to extend Trello email integration.

Matthew Hayes

I am Matthew Hayes, from Syosset, Long Island, NY. I just finished my junior year as a CS major at Cornell University upstate in Ithaca, and will be working on a FogBugz activity feed this summer. Fun fact: I caught the biggest fish on this year’s fishing trip (evidence below).

Peter Johnson

My name’s Peter, and I’m working on adding saved searches and list sorting to Trello this summer. I just finished my junior year at William & Mary in Virginia, and in my free time I enjoy running long distances and playing Dots!

Steven Lyubomirsky

If you’re inclined to take me at my word, my name is Steven Lyubomirsky, I’m a rising junior at Princeton, I study computer science, and am incredibly handsome. If you’re not, at least three of those can be independently verified. I live under the watchful guard of my blue parakeet in Fort Lee, NJ, a safe distance from the incredibly radioactive center of the universe (NYC, of course), where I like to demarcate my domain with my nightly walks. This summer I’m working on the Platform team.

David Patrzeba

My name is David Patrzeba and I am an intern on the FogBugz team (Project Jackalope). I started on June 6, 2014 because the newest addition to my family decided to arrive on my original start date of June 2, 2014. I am a NJ native and will be traveling home every weekend to be with them, but during the week I will be staying at the Clark St. residence in Brooklyn. I am a rising senior at Rutgers University (The State University of New Jersey) where I am studying Electrical & Computer Engineering, Computer Science, and Economics. Fun Fact: I served in a Special Operations unit in the Army for 7 years, and I may be Fog Creek’s oldest intern ever.

Matt wasn’t lying. He really did catch the biggest fish.

*Each year the intern class is named after the next letter in the alphabet. This year is “J”. Do you have a fantastic “K” animal name recommendation for next year? Talk to me!

Four Million to One (Or How I Handle Trello Support)

May 7th, 2014 by Brian Cervino


As we pass four million Trello members I thought it would be a good time to share with other small software development teams the fact that providing high quality support doesn’t have to be expensive or impossible.  This includes a one business day initial response window for all newly created cases and making sure to follow through on all open cases until resolution.  With just a few tools and some dedicated time, it is possible for even just one person like myself to support our entire member base.

The Trello toolbox contains a few basic items that I will go into in individual detail: help documentation via Desk, email support via FogBugz, in-app support via Trello, SnagIt for screenshots, and Google Analytics.

Help Documentation

The first level of support here at Trello is our help documentation at  I use Desk to manage our help content as they provide easily customizable themes and great tools for quickly publishing articles.  As with any help documentation the goal is to make sure that the people using Trello are able to quickly find the information they need, whether it is about getting started with Trello and creating their first board or diagnosing browser issues.  Desk provides easy ways for members to browse articles by topic and has a robust search engine for finding articles by keywords or article content.  Also, Desk offers readers polling at the bottom of each article to critique the article’s helpfulness.  This combined with people’s feedback allows me to constantly tweak articles and create more valuable help content.


With Desk I also use two other really simple tools for  The first is SnagIt.  This really basic and straightforward application is great for taking screenshots that can be quickly edited, enhanced and dropped in to a support article to provide a visual context to accompany the text.  I recently went through our help documentation and did a major overhaul, adding images and captions to as many articles as possible.  This provided a visual anchor to help our members zone in on the information they were looking for and improve their experience in the Trello help documentation.  How do I know this?  Because of…

Google Analytics.  Analytics provides useful information as to how people are getting to our help documentation, what they are looking for, and their activity within the Trello help site.  With Google Analytics I was able to see that once I had added screenshots to my articles bounce rates were going down and the exit percentage was going up, telling me that people were getting the information they needed from those articles.   I also saw that the average time spent on articles relating to a help topic went down while the average time spent on articles related to features was going up.  From this information I was able to conclude that people were finding information faster, but also interested in exploring what Trello has to offer.  Analytics can also be valuable for detecting holes where information on a subject is scant or isn’t currently covered by looking at the keywords people are searching when entering our site.


Email Support

If the help documentation doesn’t provide an answer to your question, and there are often times that it can’t, the next step is email support.  I use FogBugz, which is a Fog Creek product to track all of the support queries that are emailed in.  FogBugz does a tremendous job of creating cases for each email  allowing me to manage, filter and prioritize as well as assign and share important cases with the rest of my team.  For setting up quick responses to common questions and issues I use a feature called “snippets” that allows me to have prewritten email responses that can be generated with a few keystrokes. This saves me a lot of time which I can then dedicate to other tasks.  I figure I get up to 300 cases a week via email, this means I am usually done with the email queue by lunch each day and then I can budget some time to follow-up on replies during the afternoon.


In-app Support

We recently added in-app support for the Trello for iOS app and we will soon roll it out to the Android app as well.  The idea behind this was to support Trello within Trello from a Trello board.  It seemed silly to force people to close the app and open their browser to search for help documentation when I could provide answers to people’s questions on a board in the app.  I set up one list to tackle the really common questions and then another list where Trello members can interact with me directly in the app by asking questions on cards that I can quickly respond to.  This also helps to foster a community for our mobile platforms and a knowledge base from previously asked questions.


To check it out in the Trello for iOS app select your avatar from the boards page and then select “Help!”.  This opens the Trello iOS App board in the app where you can get answers to common questions, submit help requests, feature requests and bug reports, and see what features and bug fixes will be added to future versions of the app.

Bubble It Up

In the end, good support only goes so far if it stops with me.  If there are bugs being reported, unforeseen but obvious pain points for users in the user interface, or persistent feature requests, it is imperative to make sure that the designers, developers and managers on the team know about these issues.  We keep track of all of our bugs on (you guessed it) an internal Trello board and I keep weekly statistics of trending support issues.  The top issues are then posted in a weekly team wiki so that everyone involved in Trello is aware of what is going on with our members.  It becomes much easier to get someone’s attention and get things fixed if they are seeing the same issue posted week after week.  With a continuous release cycle in Trello our developers are able to quickly resolve these issues and I get to watch the number of cases regarding them drop off to zero.


That’s basically it!  Simple, right?

One last thing, I also check social media sites like Twitter and Facebook to see if Trello users have posted support questions there.  This is also a great time to engage with the community and see what people are saying about Trello as well.  It’s kind of the icing on the cake at the end of a busy day.

If I’ve had the pleasure of providing support for you in the past, I hope you have found it to be helpful, prompt and generally amazing.  If you’ve never had to write support, then I credit the awesome team that I work with for designing a great piece of software that is simple and intuitive and the folks like Ben and Rich at Fog Creek that paved the way for me today.

Of course, if you need support my inbox is always open.

And if you never tried Trello, sign-up – it’s free!

Trello Server Team on NodeUp Podcast

November 12th, 2013 by Brett Kiefer

The Trello server team appears on this week’s NodeUp podcast, talking about the Trello tech stack in production.

Taco Headphones


How to Share Your Trello Board, But Not Your Secrets

March 7th, 2013 by Rich Armstrong

We really liked seeing this post on how WooThemes uses Trello. We love it when people show their Trello boards. However, the screenshot has the text on the cards blurred out individually. That seems like a huge hassle. There had to be a better way to share screenshots without giving away the particulars of their board.

So we poked around on the internet and found this technique for blurring text with CSS. (Neat!) We tailored it for Trello and created a bookmarklet that we call “Blur My Board”.

Check out the bookmarklet here!

Need an example? Here’s an unaltered screen shot of the Trello dev board:


Click the “Blur My Board” bookmarklet and here’s what it looks like afterward:


Now snap a screenshot. Refresh the page and everything goes back to normal.

If only there were some aphorism we could use that would capture the concept that images convey more information than text. Oh well, we hope you enjoy the bookmarklet at least.

If you want to show us your board, get your bookmarklet here, and after you’ve blurred it, put it online somewhere and tweet us about it @trello!

Dogfooding Until It Hurts

February 26th, 2013 by Rich Armstrong

Dogfooding. Also called “eating your own dog food.” It’s pretty simple, right? If you work at Uber, maybe take an Uber car ride from time to time. If you work at Khan Academy, you’re probably pretty good at math by now.

In this video from 2009, Joel talks about dogfooding as being more than just using your own product. It’s about using your own product for everything you can imagine, even if that usage is a little uncomfortable.

We dogfood Trello, FogBugz, and Kiln in a ton of different ways.

We’re a software company, so we generate a lot of code. Kiln helps with that. But we even use it to hold things that aren’t “code” per se, such as backups of non-sensitive databases. We don’t have any real crazy use cases, like using code reviews to plan parties or the electric DAG to create subway maps, but that’s just because Kiln has only been around a few years.

FogBugz, on the other hand, we use for tons of off-label stuff. We use FogBugz’s crash reporting ability to read RSS and Twitter feeds and create cases when new items appear. We use its customer email capabilities to receive faxes. And we have a panoply of API scripts automating a bunch of different business processes.

Trello is a natural for dogfooding, of course, because it’s so flexible. We keep kitchen snack requests and lunch menus on boards. We keep track of who’s going to what conferences, and use it to plan their travel. Trello really shines in setting the agenda for and running our bi-weekly company all-hands meeting. Because Trello is so flexible, it invites a lot of different use cases. We’re still figuring out which ones really work, and it’s great to see a fast-growing user base figuring that out alongside us.

So, that’s all well and good, but if you really want to see “dogfooding until it hurts” in action, check out Beeminder, a tool for setting “goals with a sting.” You set up your goals, and if you stray from them, the service fines you an escalating amount of real money until you’re back on track. Beeminder is dogfooding heavily and publicly to keep their development goals on track. These folks are  literally giving away cold hard cash to users as a pre-commitment to do things like delivering user-visible enhancements or blog posts on a regular basis. Amazing. Even better, they have a Trello integration that’ll keep you moving those cards to the Done column regularly (or else).


Trello uses an icon font and so can you!

January 31st, 2013 by Bobby Grace

Inspired by Github’s Octicons and a desire to clean up our kludgy icon code, I set out to convert to use an icon font.

Previously, we used an image sprite method. We used a single 750×145 pixel image that contained 6 versions of each icon (two sizes and three states). We offset each icon with CSS background-image and background-position. We also loaded a sprite at double the resolution and served it to higher DPI devices via media queries.

The sprite image looked like this:

Spriting is a popular and battle-tested method. So why switch? Icon fonts are a new, modern way to implement icons. They have tons of benefits, such as…

  • They are scalable and resolution-independent. There’s no need to cut a huge 2x size image for Retina displays. Notice how fonts automatically look nice on a Retina display without any media queries or additional CSS? An icon font will, too. It also scales properly for different zoom levels on the desktop, unlike our sprite method.
  • Icon fonts are smaller. Way smaller. We compile our entire CSS into a single file, which includes the embedded sprite image. We cut down that file from 118kb gzipped to 70kb gzipped, with the font embedded. The CSS is also cleaner and much easier to use.
  • You can use regular old CSS to alter color, adjust size, and add effects like shadows and gradients and whatnot. You no longer need to cut another image for hover states or different sizes.
  • They’re easily extendable since you can use one of the thousands of open unicode code points. You don’t need to shuffle much CSS either.
  • You can do stuff like thiisssss.

I was convinced, so I set out to do the conversion. I found all kinds of interesting posts, but none of them put it all together, so I decided to create a guide. Here’s how to design and implement an icon font for your own site.

The Tools

  • Glyphs. Glyphs is a font editor for Mac. It’s the nicest app for editing vectors I’ve ever used. If you’re just creating icon fonts, you can probably just use Glyphs Mini, but those developers deserve every cent for this excellent software.
  • Adobe Illustrator. We created our icons in Illustrator, so copying into Glyphs was a breeze. You may get along just fine with only Glyphs if you’re starting anew.
  • FontSquirrel @font-face Generator. we’ll use Font Squirrel to convert our font file into various formats.

Importing Glyphs into Glyphs

You can copy and paste Illustrator paths directly into Glyphs. There are a few pitfalls you’ll want to avoid, though. Glyphs default x-height is 500 points which translates to 500px if you’ve got Glyphs set to the default grid spacing of 1 (“File” > “Font Info” > “Other Settings”). Make sure your Illustrator object is about as tall as your x height, otherwise it may be a little hard to scale when it gets into Glyphs. Also be sure to use a solid fill in Illustrator. Using a gradient fill creates some funky points and curves. Other than that, just copy your paths and paste.

More on importing from Illustrator on the Glyphs blog.

Naming Glyphs

Underneath the surface, every glyph in a font has a unique Unicode code point. For example the capital letter “A” is 0041 in Unicode. You could map your glyphs to everyday characters like “c” (0063) or “m” (006D) so that your icons will appear when you use those characters in HTML, but Unicode has something specifically for custom extensions like ours. It’s called the Private Use Area, or PUA. The PUA is the 6,400 unassigned code points (E000 through F8FF) that are meant to be used by third parties so they don’t conflict with the standard Unicode assignments. Our glyphs are like no other glyphs, so it makes sense to use this range.

As an example, Apple uses the PUA to show the the Apple logo character  (F8FF). Neat.

To assign code points in Glyphs, click the top field in the bottom left pane, then name your glyph starting with “uni” then the code point you want to use. “uniE000″ or “uniF010″, for example. You’ll know you did it correctly when see the Unicode field at the bottom of the view change. The glyph will also go into the “Private Use” section instead of “Other”. After the unicode point is set, you might be inclined to change the name to something more human readable like “search” or “info”. Resist this urge. Changing the name from the uniXXXX format might mess up the names on export.

More on glyph names on the Glyphs blog.

For more on Unicode, read “The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)” on Joel on Software.

Hinting Hints

Our sprite image looked nice and crisp because every pixel was predefined and rasterized. All browsers, for the most, render images in the same way. Fonts are different. The browser is converting paths, points, and lines to pixels. A lot can get lost in the translation. Your font will be subject to various font rendering engines, some which will finesse smooth curves and some of which will churn out jagged edges.

Hinting is the practice of adjusting your vector paths so that they line up nicely when rendered on a rasterized pixel grid. It’s what you do to make sure your icons look sharp and crisp. You’ll spend a lot of time hinting your font, and it will take a lot of testing, tweaking, and eyeballing. Here are some helpful guidelines for you to get started, though.

Trello uses two icon sizes, one at 12 pixels and one at 20 pixels. Sticking to a roughly 60 pixel grid means the output will look sharp when it’s rendered at either size. You’ll want to set the width of your glyphs to 1920, a nice, round multiple of 60 pixels. Notice how the height, width, and positioning are all multiples of 60 in the screenshot below?

We also set the units per em to 1920. The what per what? An em is a unit of measure that, basically, describes how wide it is. The units per em is a measure of how much information gets packed into a character. Higher units per em will deliver more precise fonts, but require more processing. Click here to read Microsoft’s guidelines on type hinting and production. To change the units per em in Glyphs, open “Font Info…” (the “i” button in the top right corner), select the “Font” subsection and set your “units per Em” to 1920.

Your smaller icons may need dedicated glyphs that are specially hinted to do them justice. That’s up to you. You can also use different sizes, of course. The math works out more elegantly with 16 and 32 pixel sizes, for example. Set your “units per Em” to “2048″ (or 2^11) if you go that route.

In the end, our font looked like this:

Now that you’ve decided on your sizes and hinted the heck out of your glyphs, your font is complete! Go to “File” > “Export” (or cmd-E), confirm, and you’ll have an OpenType (OTF) file waiting for you.

Converting into Multiple Formats

Browsers are picky, so we need lots of different formats to satisfy them all. Luckily there’s a tool out there that will convert OpenType files into all those formats for us. It’s called the FontSquirrel @font-face generator.

There are a few things you need to do here. First, add the font, then select the “Expert…” option below. (We are experts.) For formats, select TrueType, WOFF, EOT Compressed (if you need support for IE8 and below), and SVG. You can deselect everything in the “Fix Missing Glyphs” section. We won’t be using those.

By default, FontSquirrel won’t load glyphs in the Private Use Area. Since our font is entirely in that range, we want to make sure it’s included. To do so, select “Custom Subsetting…” in the Subsetting section. In “Unicode Ranges”, enter “E000-F8FF”. (That’s the PUA range, remember?) At this point, FontSquirrel will render a preview of all 6,400 characters in this range in the browser. This is kind of slow and you might assume your browser is broken, but it probably isn’t. Don’t be afraid. You’re an expert!

Did it work? Okay, good. You can also remove “-webfont” from the “Font Name Suffix”, unless you want your files to look like mycooliconfont-regular-webfont. You should reconsider the name My Cool Icon Font, too, actually. Next, set the “Em Square Value” to “1920″, or whatever you had your “units per Em” set to (see the Hinting Hints section above). Now click “Download Your Kit” and you’ll get a .zip file containing all the formats we need. This can also take a few seconds since FontSquirrel is basically performing a miracle for us.

Want to automate this conversion business? Check out fontforge. I can’t tell you if this actually works because I never tried, but I think it’s possible. Go figure it out.

Loading Your Font

Now that you’ve got your font in all the requisite formats, you’ll need to load them via CSS. We’ll use @font-face for that. If this sounds new or scary, it’s neither. @font-face has been around since IE4 and is supported in nearly every browser. Not all browsers support every font format, but we’ll get to that in a second. The code for loading fonts looks like this:

@font-face {
    font-family: 'Trellicons';
        url('/static/fonts/myfont-webfont.eot?#iefix') format('embedded-opentype') 
            /* This is a hack for Internet Explorer 8 and 
               below (oldIE), which can't handle multiple
               src declarations. See this Stack Overflow answer for more. 
               Also, you can delete this EOT line if you 
               don't need support for oldIE. */
        url('/static/fonts/trellicons-regular.woff') format('woff'),
        url('/static/fonts/trellicons-regular.ttf') format('truetype'),
        url('/static/fonts/trellicons-regular.svg#trelliconsregular') format('svg');
    font-weight: normal;
    font-style: normal;

Old Internet Explorer will load the embedded OpenType file (EOT) file, and most other browsers will use the WOFF file. WOFF, or Web Open Font Format, files are basically wrapped OpenType (OTF) and TrueType (TTF) files with the additional benefit of compression and extra metadata. The Android browser and older versions of iOS will use TTF, and SVG will cover any other cases.

A note about SVG. While my Mac was nicely rendering the WOFF font, I discovered Windows was not rendering so nicely. This was particularly true of Chrome on Windows, which uses its own font rendering engine. After reading this helpful Font Spring article I switched to SVG fonts, only to find that SVG fonts are not supported in Firefox or IE9+. So then I spent quite a bit of time hinting the font. Then I spent a lot more time hinting the font. It was a lot of work, but good hinting goes a long way. The icons look sharper across all browser and operating systems.

After all that, we ended up using WOFF for most browsers for a few couple reasons. First, the file was two and half times smaller than the SVG file (7kb compared to 18kb). Secondly, line height on SVG fonts behaves differently across browsers, which means the icons looked either too high or too low depending on the browser. We did end up using SVG for Chrome on Windows, since SVG fonts do not go through the default font rendering engine. They simply look the best. We load the font conditionally by adding CSS classes for the browser and operating system to the body element of the HTML via some JavaScript and User Agent sniffing. (Note: this is bad and you shouldn’t do it.) This also allows us to fix the line height fix conditionally. The code looks like this:

@font-face {
    font-family: 'Trellicons Regular SVG';
    src: url("/static/fonts/trellicons-regular.svg") format("svg");
    font-weight: normal;
    font-style: normal;
} .icon-lg, .icon-sm {
    font-family: "Trellicons Regular SVG";
} .icon-lg {
    line-height: 34px;
} .icon-sm {
    line-height: 20px;

For more on @font-face and loading fonts, check out Paul Irish’s “Bulletproof @font-face syntax” and Font Spring’s “The New Bulletproof @Font-Face Syntax”.

Building Reusable CSS

Now that we’ve got our font loaded, we need to write some more CSS in order to use it. First, we’ll set up our two different sizes.

.icon-sm {
    color: #b3b3b3; 
    display: inline-block; 
    font-family: "Trellicons"; 
    -webkit-font-smoothing: antialiased; 
        /* For more detail on this property, see Tim Van Damme's blog post. */
    font-style: normal;
    font-weight: normal;
    line-height: 1;
.icon-sm {
    height: 18px;
    font-size: 12px;
    line-height: 18px;
    width: 18px;
.icon-lg {
    height: 30px;
    font-size: 20px;
    line-height: 30px;
    width: 30px;

Now we need to go through and map the Unicode characters to CSS classes. In our font, the icon for organization is known as “F000″, the icon for board is “F002″, etc. We don’t want to write Unicode in our template every time. (Actually, we would have to write the HTML entity for the Unicode code point. Computers are awesome.) Luckily there’s an easy way to insert Unicode content in an element using only CSS. We’ll use “content” and the pseudo class “:before”. Here’s what it looks like:

.icon-org:before {
    content: "\f000";
.icon-member:before {
    content: "\f001";
.icon-board:before {
    content: "\f002";

Look, ma! No background-position! Now we can do:

<span class="icon-sm icon-org"/>


<span class="icon-lg icon-board"/>

Ta-da! Now all we need to do is convert the CSS and templates to the new… Oh… This is going to take a while…

There are a few different ways to implement the CSS/HTML. Another neat approach is to use data- attribute, a method outlined in John Hick’s 24 Ways post. This will save on markup and is more semantically correct. Also see Chris Coyier’s example here. The class based method worked best for us since it’s most similar to our codebase.

So there you have it. Every step of the process and all the reading, all in one place. Should you choose to go on this adventure, I wish you good luck! I’m glad we took the plunge. It’s a faster, more succinct, and more scalable implementation. If you have any questions, you can ask me on Twitter.

And, oh yeah, go sign up for Trello! It’s the easiest way to organize anything with anybody.

FogBugz and Trello Homebrew

September 6th, 2012 by Ben McCormack

When we launched Trello last year, we immediately heard from customers that they wanted Trello integration with FogBugz. It’s a reasonable request:

Fog Creek made FogBugz.

Fog Creek made Trello.

Fog Creek should make them play nicely together.

So over lunch, I asked one of the FogBugz developers, Why haven’t you made a Trello Plugin yet?” And he responded, “We would love to make a FogBugz plugin that integrates with Trello! What do you want to see?”

I drew a blank.

The solution wasn’t immediately obvious to me and I couldn’t think of a good design off the top of my head—certainly there is a good solution; it just wasn’t obvious to me what it should be. There are a billion different ways you might present FogBugz data in Trello. Plus, Trello is still maturing and (currently) lacks web hooks. Both of these things make integration with FogBugz a bit challenging at the moment.

There’s not a FogBugz-Trello integration plugin yet, but several customers expressed an interest, and I was sure I could help them out. We recently talked to a FogBugz customer who uses multiple Active statuses in their workflow and uses Milestones to break up sprints. Something like this:

FogBugz: All Cases in Sample Project Broken Down by Milestone

Given their workflow, their request seemed pretty reasonable. For a given project:

  • FogBugz Milestones as Trello Boards
  • FogBugz Active Statuses as Trello Lists
  • FogBugz Cases as Trello Cards, with a link back to the original case.

I decided to use the FogBugz XML API and the Trello API to see if we could make that view possible. Turns out it’s not that hard and this is what you get as a result:

Trello view of FogBugz Cases

Each card even has a little Kiwi icon that you can click to go right to the case in FogBugz (On Demand only). The script only updates one way (FogBugz => Trello), but I think it’s a nice visualization for this particular workflow. You can get the script here: Milestones to Trello.

Of course, you should modify the script to fit your needs. Would you prefer to see Projects as Boards with Milestones as Lists? Areas as Lists? Edit the script any way you like, and if you come up with something you want to share, send us an email and we’ll add it to our FogBugz recipes.

Do you have an idea for how FogBugz and Trello should play together? Let us know what’d you like to see by leaving an answer on our Trello Integration post.

Building for multiple devices

January 24th, 2012 by Bobby Grace

Trello at various sizes on multiple devicesWe built Trello from the ground up to work on just about any device. It’s not a simplified version with limited features, either. Trello responds to your device’s screen size and capabilities. It’s the same exact site and the same exact code; a consistent experience that looks, feels, and works the same everywhere.

But we also have an iPhone app. It’s pretty great if I may say so. If you are a Trello user with an iPhone, you should download it now. It’s free. Now that there is a great app, why would we still focus on a mobile web app? One reason is that focusing on mobile makes Trello better as a whole.

Everything we do for mobile translates back to a better desktop experience. This wasn’t the first reason we wanted to implement a responsive design, but it turned out to be the most important. Keeping mobile in mind focuses us on creating a fast and easy-to-use interface. Trello gets data super fast, but the page must also render quickly. That stops us from using complex interactions and some of the more whiz-bang CSS features. This translates back to rendering speed on your desktop, which isn’t likely to be an overclocked gaming rig with 32GB of RAM.

All the interface elements are mobile-friendly, which means they are also more desktop-friendly. Buttons and menus have big, friendly hit targets. Interactions are straight-forward. We don’t rely on hidden hover effects and if we’ve got a complex interaction, it will have a fallback for touch devices.

There are no redirects. Let’s say you’re on your phone and somebody links to from Twitter. You’re able to watch the video, read the pitch, sign up, and try it out. You are left with a good impression, no nonsense. No screaming “DOWNLOAD THE APP!” page, no switching out of whatever app your using, and you won’t be redirected five times and land on the homepage. You just get the information and it works.

Scaling, zooming, and resizing work seamlessly. Sometimes you want to use a small browser window on a desktop. Maybe you’ve got a side monitor with a Trello board and your mail app open while your text editor or photo editor are up on your main screen. The horizontal board view won’t work at smaller window sizes, but Trello will adapt to a view that does. If you need bigger or smaller text, you can zoom in (or out) as much as you need and Trello will use a view that works. Got a huge monitor and want to project your Trello board for all to see? Trello will work for that as well. Is it way far back in the office? Just zoom in and text will be readable.

We can deliver updates to all devices seamlessly. We have a single codebase and one place to deploy, which means updates are easy. We don’t have to retro-fit new features to a separate codebase, worry about new workflows or interactions, or think about how some URL is going to work. This lets us develop and ship features faster.

So how does it all work?

Here are some of the tools and tricks that made developing a responsive interface much easier.

Use a limited library of mobile-optimized, reusable components. Each component can be collapsed into a single column or otherwise adjusts for smaller screen sizes. The same layout elements used for the back of cards are used in the organization profile and a bunch of other pages. Our context menus (those small pop-ups used to do things like assign members and select labels) are narrow enough that they will fit on any screen. We have some one-offs like the landing page and the board, but they are few and far between. For the most part, we don’t have to ask how a new feature is going to work on mobile because any component we use will already be mobile-optimized.

Card menu on card detailThink twice about navigation. The card sidebar typically has navigation and buttons for voting, assigning, and the like. It collapses below the main column with a smaller window, which means you would have to scroll and scroll to get to that vote button you were looking for. We added a card menu to the header on the back of cards that lets you easily vote, add due dates, assign members, and everything else without wearing out your thumb.

Use a vector-based image editor like Illustrator to produce icons. We wanted to make sure icons looked sharp on devices with a higher pixel ratio like the the iPhone 4. We use a CSS sprite sheet that has every icon used on the site. We can easily export a higher resolution version using Illustrator, and serve it to capable devices using some simple CSS media queries. UPDATE: now uses an icon font for icons! Icon fonts are faster, Retina-ready, and easier to work with. You can read about our experience converting to an icon font here.

Trello icon sprite sheet

That being said…

We’re developing for the browsers and devices of today and tomorrow. We don’t have spare development time, so we can’t spend any on browsers and devices that won’t be around in two to three years. Trello won’t work on the RAZR, for instance. It also doesn’t work on every ‘smart’ device. Internet Explorer 8 doesn’t have the technical capabilities to run Trello. The Windows Phone 7.0 browser is based off of IE8, so it won’t work either. But it will work on Android 2.3+, iOS 4.0+, Windows Phone 7.5 (Mango), and others. Are we neglecting would-be happy users? Perhaps. But we can provide more value to more people by shipping features faster and that’s better in the long run.

And we still love native apps! Apps provide things we can’t get out of the web: better speed, offline support, smooth animations, push notifications, and a native look and feel. Native apps will provide a better experience to a broader reach. We just don’t think the mobile web should be ignored because of them.

Designing for multiple devices has deeply influenced our design decisions and made for a better, faster, and easier-to-use product. There are plenty of improvements to be made, but we’re happy with the foundation we’ve set. Sign up now and check it out for yourself.

The Trello Tech Stack

January 19th, 2012 by Brett Kiefer

Trello started as an HTML mockup that Justin and Bobby, the Trello design team, put together in a week. I was floored by how cool it looked and felt. Since Daniel and I joined the project to prototype and build Trello, the challenge for the team has been to keep the snappy feeling of the initial mockups while creating a solid server and a maintainable client.

The Initial Trello Mockup

The Initial Trello Mockup

That led us toward a single-page app that would generate its UI on the client and accept data updates from a push channel. This is pretty far from any of the work we’ve done before at Fog Creek, so from a technical perspective Trello has been an adventure.

Initially, we were wondering how interesting and far-out the stack could be before management got nervous, but our concerns were addressed in an early meeting with Joel, when he said “Use things that are going to work great in two years.”

So we did. We have consistently opted for promising (and often troublesome) new technologies that would deliver an awesome experience over more mature alternatives. We’re about a year in, and it’s been a lot of fun.


Trello started out as a pure JavaScript project on both client and server, and stayed that way until May, when we experimentally ported a couple of files to CoffeeScript to see how we liked it. We loved it, and soon converted the rest of the code over and started coding CoffeeScript exclusively.

CoffeeScript is a language that compiles to readable JavaScript. It existed when we started Trello, but I was worried about the added complexity of having to debug compiled code rather than directly debug the source. When we tried, it, though, the conversion was so clean that mapping the target code to the source when debugging in Chrome required little mental effort, and the gains in code brevity and readability from CoffeeScript were obvious and compelling.

JavaScript is a really cool language. Well-written CoffeeScript smooths out and shortens JavaScript, while maintaining the same semantics, and does not introduce a substantial debugging indirection problem.

The Client

The Trello servers serve virtually no HTML. In fact, they don’t serve much client-side code at all. A Trello page is a thin (2k) shell that pulls down the Trello client-side app in the form of a single minified and compressed JS file (including our third-party libraries and our compiled CoffeeScript and Mustache templates) and a CSS file (compiled from our LESS source and including inlined images). All of that comes in under 250k, and we serve it from Amazon’s CloudFront CDN, so we get very low-latency loads in most locations. In reasonably high-bandwidth cases, we have the app up and running in the browser window in about half a second. After that, we have the benefit of caching, so subsequent visits to Trello can skip that part.

In parallel, we kick off an AJAX data load for the first page’s data content and try to establish a WebSocket connection to the server.


When the data request returns, Backbone.js gets busy. The idea with Backbone is that we render each Model that comes down from the server with a View, and then Backbone provides an easy way to:

  1. Watch for DOM events within the HTML generated by the View and tie those to methods on the corresponding Model, which re-syncs with the server
  2. Watch the model for changes, and re-render the model’s HTML block to reflect them

Neat! Using that general approach, we get a fairly regular, comprehensible, and maintainable client. We custom-built a client-side Model cache to handle updates and simplify client-side Model reuse.


Now that we have the entire client app loaded in the browser window, we don’t want to waste any time with page transitions. We use HTML5 pushState for moving between pages; that way we can give proper and consistent links in the location bar, and just load data and hand off to the appropriate Backbone-based controller on transition.


We use Mustache, a logic-less templating language, to represent our models as HTML. While ‘harnessing the full power of [INSERT YOUR FAVORITE LANGUAGE HERE] in your templates’ sounds like a good idea, it seems that in practice it requires a lot of developer discipline to maintain comprehensible code. We’ve been very happy with the ‘less is more’ approach of Mustache, which allows us to re-use template code without encouraging us to mingle it with our client logic and make a mess of things.

Pushing and Polling

Realtime updates are not a new thing, but they’re an important part of making a collaborative tool, so we have spent some time on that layer of Trello.


Where we have browser support (recent Chrome, Firefox, and Safari), we make a WebSocket connection so that the server can push changes made by other people down to browsers listening on the appropriate channels. We use a modified version* of the client and server libraries that allows us to keep many thousands of open WebSockets on each of our servers at very little cost in terms of CPU or memory usage. So when anything happens to a board you’re watching, that action is published to our server processes and propagated to your watching browser with very minimal latency, usually well under a second.


It ain’t fancy, but it works.

Early Architecture Drawing

Early Architecture Drawing

When the client browser doesn’t support WebSockets (I’m lookin’ at you, Internet Explorer), we just make tiny AJAX requests for updates every couple of seconds while a user is active, and back off to polling every ten seconds when the user goes idle. Because our server setup allows us to serve HTTPS requests with very little overhead and keep TCP connections open, we can afford to provide a decent experience over plain polling when necessary.

We tried Comet, via the downlevel transports for, and all of them were (at the time) shaky in one way or another. Also, Comet and WebSockets seemed to be a risky basis for a major feature of the app, and we wanted to be able to fall back on the most simple and well-established technologies if we hit a problem.

We hit a problem right after launch. Our WebSocket server implementation started behaving very strangely under the sudden and heavy real-world usage of launching at TechCrunch disrupt, and we were glad to be able to revert to plain polling and tune server performance by adjusting the active and idle polling intervals. It allowed us to degrade gracefully as we increased from 300 to 50,000 users in under a week. We’re back on WebSockets now, but having a working short-polling system still seems like a very prudent fallback.

The Server

  • node.js
  • HAProxy
  • Redis
  • MongoDB


The server side of Trello is built in Node.js. We knew we wanted instant propagation of updates, which meant that we needed to be able to hold a lot of open connections, so an event-driven, non-blocking server seemed like a good choice. Node also turned out to be an amazing prototyping tool for a single-page app. The prototype version of the Trello server was really just a library of functions that operated on arrays of Models in the memory of a single Node.js process, and the client simply invoked those functions through a very thin wrapper over a WebSocket. This was a very fast way for us to get started trying things out with Trello and making sure that the design was headed in the right direction. We used the prototype version to manage the development of Trello and other internal projects at Fog Creek.

By the time we had finished the prototype, we were good and comfortable in Node and excited about its capabilities and performance, so we stuck with it and made our Pinocchio proto-Trello a real boy; we gave it:

Node is great, and getting better all of the time as its active developer community churns out new and useful libraries. The huge amount of continuation passing that you have to do is an issue at first, and it takes a couple of weeks to get used to it. We use a really excellent async library (and the increased code brevity of CoffeeScript) to keep our code under control. There are more sophisticated approaches that add features to JavaScript to automate continuations, but we’re more comfortable with just using an async library whose behavior we understand thoroughly.



We use HAProxy to load balance between our webservers. It balances TCP between the machines round robin and leaves everything else to Node.js, leaving the connections open with a reasonably long time to live to support WebSockets and re-use of a TCP connection for AJAX polling.


Trello uses Redis for ephemeral data that needs to be shared between server processes but not persisted to disk. Things like the activity level of a session or a temporary OpenID key are stored in Redis, and the application is built to recover gracefully if any of these (or all of them) are lost. We run with allkeys-lru enabled and about five times as much space as its actual working set needs, so Redis automatically discards data that hasn’t been accessed lately, and reconstructs it when necessary.

Our most interesting use of Redis is in our short-polling fallback for sending changes to Models down to browser clients. When an object is changed on the server, we send a JSON message down all of the appropriate WebSockets to notify those clients, and store the same message in a fixed-length list for the affected model, noting how many messages have been added to that list over all time. Then, when a client that is on AJAX polling pings the server to see if any changes have been made to an object since its last poll, we can get the entire server-side response down to a permissions check and a check of a single Redis value in most situations. Redis is so crazy-fast that it can handle thousands of these checks per second without making a substantial dent into a single CPU.

Redis is also our pub/sub server, and we use it to propagate object change messages from the server process making the initiating request to all of the other server processes. Once you have a Redis server in place, you start using it for all sorts of things.


MongoDB fills our more traditional database needs. We knew we wanted Trello to be blisteringly fast. One of the coolest and most performance-obsessed teams we know is our next-door neighbor and sister company StackExchange. Talking to their dev lead David at lunch one day, I learned that even though they use SQL Server for data storage, they actually primarily store a lot of their data in a denormalized format for performance, and normalize only when they need to.

Trello Today

In MongoDB, we give up relational DB features (e.g. arbitrary joins) for very fast writes, generally faster reads, and better denormalization support — we can store a card’s data in a single document in the database and still have the ability to query into (and index) subfields of the document. As we’ve grown quickly, having a database that can take a fair amount of abuse in terms of read and write capacity has been a very good thing. Also, MongoDB is really easy to replicate, back up, and restore (the Foursquare debacle notwithstanding).

Another neat side benefit of using a loose document store is how easy it is to run different versions of the Trello code against the same database without fooling around with DB schema migrations. This has a lot of benefits when we push a new version of Trello; there is seldom (if ever) a need to stop access to the app while we do a DB update or backfill.
This is also really cool for development: when you’re using hg (or git-) bisect and a relational test DB to search for the source of a bug, the additional step of up- or downgrading a test db (or creating a new one with the properties you need) can really slow things down.

So we like it?

We like our tech stack. As Joel observes, we’ve bled all over it, but I’ve never seen a team make an interesting app without tool- and component-related bloodshed, and not everyone can say that they really like what they’ve ended up with. As is true of most applications, no component or implementation detail is necessary to its nature; however, we think that this excellent set of open-source projects has sped up our development, left us with a solid and maintainable code base that we’re eager to move forward with, and made Trello a more responsive and beautiful app. Thanks to everyone who has contributed to them; it’s a great time to be a programmer.

Sound neat? Try Trello! It’s free.

Just can’t get enough tech stack talk? Here’s a Prezi I made for a recent talk on Trello.

* The server currently has some problems with scaling up to more than 10K simultaneous client connections when using multiple processes and the Redis store, and the client has some issues that can cause it to open multiple connections to the same server, or not know that its connection has been severed. There are some issues with submitting our fixes (hacks!) back to the project – in many cases they only work with WebSockets (the only transport we use). We are working to get those changes which are fit for general consumption ready to submit back to the project.

Looking for more?

Visit the Archives or subscribe via RSS.