Talking Treesaver

Jun 07, 2011 |

Video from my portion of the Designing for iPad and Other Mobile Devices panel at the 2011 International Symposium on Online Journalism is now available online:

You can view the presentation slides here:

Bonus: A few weeks ago, I did a Portuguese-language interview about Treesaver with Pedro Telles for the podcast. If you speak Portuguese (or even if you don't), you can listen online or download the MP3 directly.

Treesaver on The Big Web Show

Mar 17, 2011 |

Scott Kellum and I were on the Big Web Show today with Jeffrey Zeldman and Dan Benjamin today talking about web design, dynamic layout, and a bit of the history about how Treesaver came to be. You can view the full video (or download audio here): Treesaver on the Big Web Show.

Dan's also posted some bonus material here: Treesaver After Dark.

The Pareto Browser Filter

Mar 15, 2011 |

Obidos, Portugal

Lately, I've been a fan of using the following conditional as a quick high-pass filter for modern browsers:

if (document.querySelector && window.localStorage && window.JSON) {
  // Passes for:
  // IE8+
  // FF3.5+
  // Safari 4+
  // iOS Safari 4+
  // Android 2.1+
  // Chrome
  // etc

With the release of IE9, this test passes for the current and previous version of all major browsers. Depending on which browser usage statistics you use, this covers 70 to 80% users. For that reason, I call it the Pareto Filter, a nod to the Pareto Principle a.k.a. the 80-20 rule.

Aside from serving as an effective filter for older browsers, these three pieces of functionality (especially querySelectorAll) are incredibly useful when building modern applications. Being able to count on fast, bug-free implementations saves a lot of headaches (and download time) for authors.

Once IE8 market share falls (which will probably take a while since IE9 doesn't work on Windows XP), I look forward to adding document.addEventListener to this filter. IE's non-standard event model has always been a pain when trying to write compact cross-browser code.

If space is a concern, you could drop the querySelector test. If you already don't care about IE8, add document.addEventListener.

Treesaver Open Source Release

Feb 07, 2011 |

Roger Black and Filipe Fortes

I'm happy to announce that the source code for the Treesaver.js Framework is now public. I'm still working on fleshing out the documentation, so let me know which parts are confusing or just require more explanation. The best place to start right now is the Walkthrough, a simple tutorial that goes through the steps of using Treesaver for some sample content.

My business partner in crime, Roger Black, has written up the history of Treesaver, describing how (and partially why) we're on this crazy mission to change the world of online reading.

Here's to an interesting 2011!

Treesaver gets Scobleized

Dec 15, 2010 |

Robert Scoble intereviewed me about Treesaver yesterday, here is the video:

Introducing Treesaver

Aug 11, 2010 |

The word is out about my latest venture: Treesaver. Nomad Editions is our first customer to make a public announcement, you can see their promotional video below:

The response and interest so far has been fantastic, and it's great to finally be able to talk about what I've been working on for the past several months.

We've been getting a ton of questions, and I thought I'd take some time to answer the most common ones.

What is Treesaver?

It's a way to make column and page-based layouts using HTML, CSS, and JavaScript. Text and image layout is tailored to fit whatever screen the user is using, in order to create a attractive, usable experience. Here's a video demonstrating how Treesaver adapts to a changing window size:

Why use HTML?

There are many reasons to use HTML, but the most important ones in our opinion are:

  • Lingua Franca of the Internet: HTML is supported by an incredible variety of devices, from expensive desktop computers to cheap mobile phones.

  • Linking & Search Engines: Articles within Treesaver websites have their own URL which can be linked to or spidered by search engines. Users searching in Google can be taken directly into the rich Treesaver experience.

  • Bookmarking & Social Media: Because Treesaver can run in the browser, users can bookmark and directly link to articles when sharing with friends. Friends and Family can immediately view shared content in a rich experience without having to go to an app store to download a viewer.

  • Leverage existing content: Treesaver articles are simply-structured HTML files, meaning little to no conversion is required for existing text content. Existing web assets like video and Flash can continue to be embedded (assuming the browser/device supports Flash, of course).

  • Ecosystem: Because Treesaver is built upon standard technologies, it can leverage the wide variety of tools available in the web ecosystem: Google Analytics, embedded YouTube videos, slideshow widgets, etc.

  • Embedding: You can embed a Treesaver article within other webpages, as you would a YouTube video. Embedded articles continue to be formatted by Treesaver, meaning branding and advertising are preserved, even if the article has been embedded on another site.

What are Treesaver's Browser/Device Requirements?

The column and page-based layout works on most modern browsers, specifically:

  • Internet Explorer 7 and above
  • Firefox 2.0 and above
  • Safari 3 and above (including iPhone, iPad, and many smart phones)
  • Chrome 3 and above
  • Opera 10 and above

Because Treesaver content is just HTML, it degrades gracefully onto legacy devices. Users with IE6 or older phones will still be able to read any article that uses Treesaver, although it will have a simpler, primarily text layout.

Can Treesaver content be distributed via the App Store?

Yes. We will provide the ability to package Treesaver content as an application that can be downloaded and sold through the App Store.

When can I use Treesaver?

We're not giving public access to Treesaver right now, although we will be doing a limited beta test in the coming weeks. Subscribe to the Treesaver mailing list to be notified when beta invites are ready to be sent out.

I'm interested in using Treesaver for my publication, how do I get in touch?

Contact us via the Treesaver website.

Will Treesaver be Open Source?

Yes. I'll be releasing the client libraries Treesaver under an open source license later this year (it's not quite ready yet, I have to remove all the dirty words first).

Got any Screenshots?

Sure, here are a few from a Nomad Editions sample issue:

Treesaver in Chrome on the Mac

Treesaver in Firefox on Ubuntu

Treesaver in IE

Treesaver on the iPad

Treesaver on the iPhone

More Questions?

Ask @treesaver or @fortes on Twitter.

Treesaver Sneak Peek

Aug 07, 2010 |

Coming Soon

Jul 27, 2010 |


Soft Hyphenator

Feb 14, 2010 |

Soft Hyphenator

I'm happy to announce Soft Hyphenator , a simple utility I wrote this weekend that adds soft hyphens into HTML content.

Today's web browsers don't provide hyphenation, which makes justified text prone to rivers of white space. However, browsers do support the soft-hyphen: the ­ HTML entity. Soft hyphens tell the browser where it can break a word, if necessary.

Adding these hyphens manually is quite tedious. The Soft Hyphenator takes HTML and adds the soft hyphens automatically.

The site is written in Python and deployed on Google AppEngine. It uses the BeautifulSoup and python-hyphenator libraries, along with OpenOffice's hyphenation dictionaries. For the nerdy & curious, I've made the source code public.

I'm still quite new to Python and Google AppEngine, but I'm pretty happy with both so far. The entire site took less than 24 hours to write, and WTF/minute rate was pretty good.

jMetronome: Using jQuery to keep typographic rhythm

Aug 05, 2008 |

Michael Arenella & his Dreamland Orchestra

A couple of years ago, Richard Rutter wrote Compose to a Vertical Rhythm, which described how web developers could use CSS to maintain proper vertical typographic rhythm when designing pages. The technique is fairly straightforward, requiring some basic math to ensure consistent margins and leading across all page elements.

One issue that many people face with this technique, is that vertical rhythm can easily be thrown off by non-text elements, such as images. To illustrate, here's a sample page which contains text, images, a code block showing a horizontal scrollbar, and even a video. Notice how the text no longer lines up perfectly within the vertical grid lines after the first image. This is because the image is 240 pixels tall, which is not a multiple of 18, the line height used throughout the document.

One solution to this issue is to make sure your images always have a height that is a multiple of the line height being used by your document. Unfortunately, this is usually not practical for production sites.

Here's some jQuery code that you can use in order to make sure your document keeps its rhythm:

$(function() {
  var lineHeight = parseInt($('body').css('line-height'));
  function balanceHeight(el) {
      var h = $(el).outerHeight();
      var delta = h % lineHeight;
      if (delta != 0)
        /* For images and objects, we want to align the bottom w/ the baseline, so we
         * pad the top of the element. For other elements (text elements that have a
         * scrollbar), we pad the bottom, to keep the text within on the same baseline */
        var paddingDirection = ($(el).is('img') || $(el).is('object')) ?
                                              'padding-top' : 'padding-bottom';

        /* Adjust padding, because margin can get collapsed and cause uneven spacing */
          var currentPadding = parseInt($(el).css(paddingDirection));
          $(el).css(paddingDirection, currentPadding + lineHeight - delta);

  /* Depending on your content, you may want to modify which elements you want to adjust,
   * by modifying the selector used below. By default, we grab all img, pre, and object
   * elements. */
  $('img, pre, object').each(function() {
      /* Only works if we're manipulating block objects */
      if ($(this).css('display') == 'inline')
          $(this).css('display', 'block');

      /* Images need to load before you get their height */
      if ($(this).is('img'))
          $(this).load(function(){ balanceHeight(this); });

The code is fairly straightforward. Briefly, what it does is add padding to the top or bottom of an element in order to ensure its total height is a multiple of the document's overall line height. Here's the same sample page as before, but this time using the script above.


You can use this script as-is, but you may want to change the selector used in the following line:

$('img, pre, object').each(function() {

The reason is that this selector is probably too broad for your page. You most likely do not want to adjust every single image on your page, just the ones within your main content block. On my page, I adjust any pre elements, because I've set them to overflow with scrollbars, which can alter the height of the code block and mess up vertical spacing just like an image.

Known Issues

I've only found two issues with the code, and they both affect Internet Explorer:

  1. object tags don't get adjusted (see the Vimeo video at the bottom of the sample page). This might be a jQuery issue, but I haven't investigated it yet.
  2. If you use unitless line heights, jQuery doesn't retrieve the correct line height in IE. You can either modify the code and hard code a line height, or just don't use unitless line height on the body element

Let me know if you run into any other issues.