Jan Miksovsky’s BlogArchive AboutContact

2013

Paper can be faster than gadgets: a printable 2014 wall calendar for more efficient scheduling discussions

I’ve posted an app that lets you print a free wall calendar that can make your scheduling discussions go faster.

This is based on a printed calendar I created by hand for some years now. As I noted in that post, most wall calendars contain far too much junk. Most professionals I know track future events in an online calendar, not a wall calendar, so among other things, you may not actually need room to write on a wall calendar these days. But it is handy to be able to quickly answer questions about what day of the week a given date falls on, or vice versa. While you can whip out a mobile device and answer those questions, this is one case where I believe paper is faster than gadgets.

Year Calendar

If you hang one of these on your office or conference room wall, I think you’ll find it useful. Each year, the startup I founded continues to print out a huge version of this calendar. (Tip: print it as a poster at Fedex). It works great for planning agile development sprints.

Optimizing for text legibility

I've tried to remove everything from this calendar that’s not strictly necessary to answer the key day/date scheduling questions. In particular, to improve legibility at a distance, I’ve tried to maximize the size of the date numbers so they can be read from far away. In the case where a single month requires six rows to display, I tuck the name of the month on the same row as the first week. Such a week can contain at most two dates on the far right. For example, in a typical U.S. calendar, this situation will come up in March 2014:

Three Months

This trick lets me save a row for the tall months. Reclaiming that vertical space means the dates can be bigger and more legible at a distance.

A web component wall calendar

Instead of creating another one-off paper calendar this year, I realized I could use web components to create a live app without too much trouble. I already had a month calendar component (available for your own web components app via Bower). This component handles most of the date math, so it was fairly straightforward to just stick twelve instances of this component together, then apply some styling and glue logic, and end up with a live calendar app.

Generally speaking, that process is what I see most web app design and development moving toward: 1) a search for the best components, 2) some wrangling to glue them together, and 3) the application of styling to achieve the desired aesthetic. The core .html source for the app is tiny, weighing in at a little over 13K, and most of that is markup or CSS. Looking just at the JavaScript, there are only about 100 lines of code.

This web app is slightly unusual in that it focuses on printing, and the web isn’t particularly print-friendly. As far as I know, it’s hard to say: “Scale this text to be as tall as possible, subject to this layout, and still have everything fit on a page.” I ended up having to be most conservative than I would have liked, tuning the app for U.S.-centric “Letter” sized paper, which is shorter than the A4 paper used nearly everywhere else. Some space goes to waste which could have been used for more generous text sizing and spacing.

Falsehoods designers believe about time

A while back, Noah Sussman posted a great list of Falsehoods Programmers Believe About Time. Designers make most of the same incorrect assumptions as well. When I read a list like this, the lesson I take away is that most people (including me) shouldn’t be doing date math or creating UI elements that depend directly on it. Instead, they should be building on top of work others have done.

In this particular case, I’d already invested a bunch of time doing the work to be able to create a month calendar component that can easily be reused in other applications. This component avoids at least a few of the Falsehoods About Time listed above. E.g., given a date, to calculate the next date it doesn’t just add 24 hours, but does some gyrations to handle daylight saving time edge cases.

A designer or developer can hopefully drop this month calendar component into their web app and get a useful result with having to worry about (or even be aware of) the edge cases. The component itself undoubtedly has edge cases it fails to handle; there are Falsehoods About Time which aren't addressed yet. But the value of doing this as a component is that at least such work is spread across applications. Others can pitch in, and we can collaboratively work towards a bug-free solution.

Global support for hundreds of languages/locations

In past years, people have asked me for “international” versions of the wall calendar that have Monday as the first day of the week, instead of Sunday the way most Americans prefer it.

Since my month calendar component already leveraged the excellent Globalize.js library, it was actually easier for me to just let the user pick the language/location they want a calendar instead of having to hard-code support for specific formats. To simplify things, I created a component that wraps the Globalize list of supported language/location combinations. Then it was just a matter of wiring the language/location selector to the calendar, and — boom! — the calendar instantly got basic support for hundreds of language/locations.

The results are likely imperfect for many places, but for languages and locations with small populations, this printable wall calendar might already be the best solution out there.

If you’re like me, it’s a good five minutes fun to just pick cultures and see what their calendars might look like. I knew that cultures in the Americas tend to prefer having a calendar start on Sunday, while European cultures tend to prefer that weeks start on Monday. This holds true even when the same language is spoken in both hemispheres: see English (U.S.) vs English (U.K.), or Spanish (Mexico) vs Spanish (Spain). Until I started working with Globalize, though, I hadn’t realized that there were cultures that prefer weeks start on a Saturday. Here’s how March 2014 looks in three settings, English (U.S.), French (France), and Arabic (Saudi Arabia):

US Calendar

French Calendar

Arabic Calendar

The start-of-week day, plus the month and day names, all come for free from Globalize. (I don’t actually know if people in Saudi Arabia want their months to look like the one above, but couldn’t find conclusive evidence of a single preferred style.)

Localize your UI and get fun surprises for free!

One last bit I thought was funny was rediscovering that, even when building atop a localization library or a localization-aware component, there are always surprises. I think this can be expressed as a law of UI design: For any user interface layout that looks good for most cultures, there exists a culture that will break that layout.

Here, the clever packing of the month name into the first row of a six-week month (as shown above) looks great in almost all the languages defined by Globalize. In that layout, the month name can span up to five columns’ worth of width, which is more than enough in most cases. But per the above law, there must exist at least one culture for which this layout does not work without modification. And such a culture does, in fact, exist:

Sami Calendar

This is the Sami language of northern Scandinavia (“sääm´ǩiõll” in the calendar’s language/location list), in which the month of March is called “pâ´zzlâšttammään”. In a year like 2014, where March starts on a Saturday, the month name will overlap with the date for March 1st. To the 25,000 or so speakers of Sami: I’m very sorry about this.

Some lessons from an open source project that never gained critical mass

I recently announced that I was halting development on QuickUI, and thought it would be a good idea to do a little post-mortem before moving on.

The good side: As a framework for web application UI development, QuickUI measured up to its design goals. It was useful for creating complex application UIs with a good separation of concerns between UI components. The core framework was highly reliable with a fairly tight abstraction and acceptable performance. QuickUI was used in some companies for real production apps with real users. The very small number of developers who actually used the framework said they liked it and were impressed by what it could do.

The bad side: As an open source project, QuickUI never achieved critical mass. QuickUI was my first attempt at kickstarting an open source project to help establish an ecosystem for component-based web user interfaces. I’d initially held the naive view that simply publishing something as open source (which I did in late 2009, two years into QuickUI’s development) would, on its own, generate community interest and participation. But the universe of open source development projects is vast, and simply making something free doesn’t make it popular. Free products still need to appeal to their audience and gain adoption through a good feature set, great distribution, and substantial luck. Eventually, QuickUI was overtaken by open web component standards (which is a good thing), and it no longer made sense to continue investment in QuickUI. Before moving on, I wanted to write down some of the lessons the QuickUI project held for me.

  1. People care about the stack of technologies beneath your project. I used to think that all that mattered is whether a tool worked and was easy to use, but most developers make demands the construction of the tool itself: programming language, runtime platform, dependent libraries, etc. The most common reason someone will offer for this is that they may need to diagnose a bug in the code and fix it. That may also be true, but I think most people have less glorified reasons for considering the technology behind a tool.

    First, simply understanding the vocabulary associated with a given stack requires investment. Occasionally you come across a tool on GitHub whose Readme says the tool can be configured via a .foo file, where the location and syntax of a .foo file is completely obvious to current users of that tool’s stack. If you don’t already know what a .foo file is, you’re less likely to adopt that tool.

    Second, a developer toolchain is a creaky, cantankerous beast, and incorporating multiple stacks of tech is a pain. This is less about debugging than what Bruce Sterling refers to as the wrangling required to get things to work together.

    Third, you trust tools on stacks that have worked for you in the past, and are skeptical that tools on unfamiliar stacks will actually work as advertised. For example, I’ve hardly ever used Ruby, and rarely use Ruby gems. When I see a tool published via npm, I feel comfortable installing and using it, even if I never look at its source, because I’ve used many tools that way. If I see a tool that does the exact same thing published as a Ruby gem, I view its efficacy as black magic.

    Last, people implicitly trust other people who have selected the same technology stack. “If someone has made the same technology choices I have, they must be as enlightened as I am!” Conversely, people look askance at those who make different choices. A die-hard plain JavaScript coder may view the Clojure community are pot-smoking hippies, while the Clojure developer may view the original party as a latter-day COBOL dork lacking sufficient brainpower and awareness.

    In the case of QuickUI, when I started on it in late 2007 or so, I was most comfortable writing in C#, so when I needed to write a build-time compiler for UI markup, I wrote it in C#. Bad idea. Despite the fact that there was no run-time need for .NET, and that the compiler ran perfectly well on a Mac (under Mono), no one would take it seriously with the taint of .NET on it. I was eventually able drop the compiler altogether, and rely on a stack of tools which jQuery developers were already familiar, but that cost the project time and effort.

  2. Using anything other than native web technologies — plain HTML, plain JavaScript, and plain CSS — significantly constrains your audience. This is similar to the above point, but pertains to your project’s source code rather than the stack of technologies supporting that source. Again, part of the argument here is that they might theoretically need to dive into the runtime source to diagnose a problem, but I think the reaction is usually more instinctive than that.

    At one point in the development of QuickUI I discovered that working in CoffeeScript was much more productive for me than in plain JavaScript. In short order, I ported the QuickUI runtime to CoffeeScript. Switching to CoffeeScript was a huge productivity boost for me — but represented a huge reduction on the potential audience for QuickUI.

    For one thing, it seemed nearly impossible for me to get potential developers to ignore the presence of CoffeeScript. CoffeeScript compiles to plain JavaScript, but anyone who looked at the QuickUI source repo saw “CoffeeScript” listed as the primary language… and walked away. They might say, “Your project looks interesting, but I don’t know CoffeeScript.” I’d tell them they didn’t need to know CoffeeScript — that was an implementation detail — but they’d already decided they were uninterested.

    Over and over, the general feeling was, “I just don’t want to use something that uses something I don’t already know.” And then, of course, for most people who really did want to be able to grok the source, CoffeeScript was a non-starter.

    To build a community around a project, you probably want as many people as possible to be able to participate. Even if you hate JavaScript, it’s the web’s lingua franca. Using any other language for an open web project may not be an insurmountable obstacle, but at the very least it’s a significant handicap. As much as it pained me, when I started up the subsequent Quetzal web components experiments, I did so in plain JavaScript.

  3. Everyone will insist there is one thing you must do that will make your library more acceptable — and all those things are different, and all those things together are probably still insufficient. Over the course of the past few years, I have given many, many QuickUI demos, and received feedback on all aspects of the tool, the accompanying site at quickui.org, the learning process, etc. Very little of this feedback was consistent; everyone fixated on something different. I thought, if I just respond to all the feedback, surely at some point the barrier to adoption will be low enough that people will start adopting the tool.

    On the basis of such feedback, I spent a huge amount of time improving things. Early on, someone said I should move the source to GitHub, so I did. Someone said it needed better documentation, so I wrote a lot of documentation. As discussed above, numerous people suggested moving away from .NET, so I did. Someone suggested having live examples of UI components, so I built those. Someone thought a tutorial would be helpful, so I made an interactive tutorial. (Which many people complimented. Thank you!) One person’s key complaint with the entire framework was that the home page didn’t have icons; if the framework was to be successful, the home page needed little icons to indicate which browsers were supported by the framework. I did that. I received many, many other suggestions, and I incorporated almost all of them.

    None of it mattered. The feedback was actionable, and probably much of it was accurate, but even addressing (nearly) all of it wasn’t enough to make the project successful.

    The fact is that most people are unwilling to invest the time to understand, analyze, and articulate what’s really wrong with your project. Of the people who gave me feedback, few of them actually looked hard at it, very few had actually tried it beyond the online tutorial, and very, very few were willing to speak directly to their key concerns. This is all understandable — people are busy, spending time on a framework of unknown value is potentially wasted, and most people want to be nice to you — but feedback on a project should be accepted with these phenomena in mind.

  4. Paradigm shift is prohibitively expensive. Early on, one person told me that building UI in a component-oriented fashion represented a significant paradigm shift — and that represented a potentially insurmountable obstacle for QuickUI.

    The problem with a paradigm shift is that it’s hard to even have a conversation with someone whose conceptualization of the world doesn’t even allow them to recognize the problem they have. I spoke with many developers who viewed the undifferentiated pile of JavaScript generating their UI as the way things had to be done. They were more concerned with getting their UI to work across multiple browsers than to worry about componentization — even though a good component library is exactly the sort of thing that would have made cross-browser work more manageable. (The cross-browser hacks could have been folded into the components, allowing them to work at a higher level of abstraction, etc.) Interestingly, these same developers would carefully factor their code into classes or functions with clear lines of responsibility. They applied good factoring to every other thing they coded except their web UI.

    Over the past year or so, Google and others have been evangelizing a component-oriented paradigm for web development. At some point, we’ll go through some phase-change where that paradigm will suddenly become dominant. I’m betting that change will happen before late 2015. By then, it will be hard to find a good web UI developer who doesn’t think of their UI in terms of components.

  5. People are only interested in something if others are already using it. This is true for both seasoned developers and novice developers — but for different reasons. The novice teaches themself jQuery or Backbone or LESS because experienced people use those things, which means they’re probably interesting and useful. The seasoned developer picks up a new tool that others are using because the alternative — using something with a tiny user base — represents unacceptable risk.

    This last point was made to me by the most abrasive person I ever spoke with about QuickUI. In fact, I think it’s because they were untroubled by politeness that they could speak the truth. They said: “I would love to use this, but I can’t. If something were to happen to you, I would be stuck having to fix your bugs. I made a bet like this in the past, and was stuck supporting someone else’s framework. I won’t do that again. Come back when lots of other people are using this.”

    So this developer had, at some point, found a great piece of technology, developed by someone else, and they staked their own reputation on adopting this technology, only to have it completely fall apart when the other party went away (went bankrupt, was acquired, whatever). It’s probably safe to assume that most seasoned developers have had a similar experience. For every open library, there must exist some critical mass at which the library’s community becomes self-sustaining.

    At that point, if you find a bug in the library, someone else in the community has probably also found the bug, and maybe even fixed it. Enough other people are invested in the library that, even if the original developer disappears, the remaining investors will keep it going for as long as that makes technological sense.

    I’d be very interested if someone could pinpoint the size of that critical mass. I’m guessing the number is pretty small: perhaps 10 active contributors might be sufficient to create the perception the library is well-maintained and not going away. Whatever that size is, I couldn’t grow QuickUI to that size.

  6. Google could publish a JavaScript library for cloud-based ham sandwiches and a thousand people would immediately star the repo on GitHub. For much of my career, I focused my attention almost entirely on the value a product created, and gave very little thought to how a product would be distributed. Distribution is, in fact, at least as important, and maybe more important, than underlying value. That’s certainly true in the short term. And, over the long term, well, maybe technology changes quickly enough that the long term never comes into play.

    I’m not saying individuals can’t launch successful open source projects, but rather that doing so within the context of a company with name recognition and a developer outreach program makes it much, much easier. The people working within such a context may not realize it. I once heard someone describe people who work at big companies as “basketball players on the moon”. Those people can jump very high, but they may not realize the extent to which their performance depends on that context.

    I have deep respect for a person who can launch something entirely on their own, without relying on the backing of their company (or industry name recognition predicated on work they launched previously at some earlier company). If someone can make a disruptive technology successful entirely on its own merits, both that tech and that person are impressive indeed.

Ah, well, live and learn. I’m still looking forward to watching the web’s UI component ecosystem take shape, because we’ll all get to make awesome stuff together.

Ending active development of QuickUI

I’ve decided to end further investment in the development of the QuickUI web user interface framework.

I’ve spent the past half-year experimentally porting various QuickUI components to HTML custom elements under the rubric of a project called Quetzal. That project makes use of Google’s Polymer project, which supports the deployment of web components to mainstream browsers. While the Quetzal element collection doesn’t yet offer the complete set of QuickUI components, and working on top of Polymer has been shaky at times, Polymer is becoming good enough for real use, and the advantages of building with web standards will quickly outweigh any proprietary advantages which QuickUI could offer.

I started QuickUI a number of years ago because it seemed clear to me that a component-oriented approach to UI design and development would let you create better and more maintainable user experiences. I didn’t see anyone else working on that in an open way, and so began my own effort to make progress in that area.

The current wave of web component standards embody many of the ideas I was pursuing in QuickUI. For fun, I just dug up from my notes the earliest source code I could find for the component markup language I thought would be useful for creating web components. Here’s sample QuickUI markup I wrote at the very beginning, probably late 2007:

<control name="taskPage" arguments="name pageTip content">
  <style>
    h1 { font-face: Arial; }
  </style>
  <script>
  function foo() { }
  </script>
  <template>
    <div ...>
      <h1>%name%</h1>
      <p class="pageTip">%pageTip%</p>
      <div id="#content">
        %content%
      </div>
    </div>
  </template>
</control>

Here’s the corresponding source code in late 2013 for the same custom element in Polymer:

<polymer-element name="task-page" attributes="name pageTip">
  <script>
  function foo() { }
  </script>
  <template>
    <style>
      h1 { font-face: Arial; }
    </style>
    <div ...>
      <h1>{{name}}</h1>
      <p class="pageTip">{{pageTip}}</p>
      <div id="#content">
        <content></content>
      </div>
    </div>
  </template>
</polymer-element>

Aside from minor syntactic differences (curly braces are in vogue now instead of percent signs; “attributes” instead of “arguments”; the style tag needs to be inside the template instead of outside; the element name requires a hyphen), the source code is nearly identical. In other words, the source code I wanted to be able to write in 2007 is essentially the source code I can now write today. Hooray for the open web!

Going forward I’ll be using web components for my own work rather than QuickUI. If you have been using QuickUI or were interested in QuickUI, I would encourage you to look at adopting web components instead, either through the Polymer project or through similar projects such as Mozilla’s x-tags.

I’ll continue to keep the quickui.org site live for the indefinite future. In particular, for the time being I’ll continue to use this blog to post thoughts on developing user interfaces, with a focus on using web components. To those of you that used QuickUI or provided feedback on it, I’d like to offer my warm thanks for all of your support. Best, Jan Miksovsky

Filling in base class slots with the awesome new capability of the shadow element

In a post a few months back, I discussed how custom elements needed an easy way to fill in slots defined by their base classes. The capable folks on Google’s Blink team have now fixed this problem with a small but critical Shadow DOM change, and I wanted to take a moment to walk through an example of how the feature works and explain why this is so cool.

What does “filling in a slot” mean, and why does it matter? The crux of the issue, for us to be able to share web components, I need to be able to create a new web component that defines some, but not all, of its appearance. I need be able to define certain places that you can fill in with your content. Those are the slots: points of visible user interface extensibility.

Example: a series of page templates

The post linked above offers a simple button example, but let’s walk through a more realistic example using a series of page templates. (If you have Google Chrome Canary installed, you can follow along with a live demo.) These sample templates will span a range of general-purpose to very specific. For the sake of clarity, the examples are overly simple, and are intended just to convey a sense of how such templates might be used to build a simple online store app. The same principles shown here could easily be extended to arbitrarily complex interfaces.

Page Template 1
A page-with-toolbar

We start with a completely general-purpose <page-with-toolbar> element that defines a page with a toolbar. For the sake of argument, let’s suppose there’s something fancy about the presentation here — perhaps the toolbar starts out at one size, and then, as the user scrolls, the toolbar becomes smaller and permanently docked at the top of the page. Regardless of what exactly makes this interesting, let’s assume that interesting stuff entails web ninja tricks the average designer or developer doesn’t have the time to learn or implement for themselves. Significantly, some aspect of the toolbar behavior requires real code, not just CSS styling.This user interface pattern is completely general-purpose, so perhaps this template is found in an online library of general-purpose web components. The key extensibility feature here is that the element defines two slots which consumers of the <page-with-toolbar> element can fill in: a toolbar slot at the top, and a main content slot.

Page Template 2
A store-page partially fills in a page-with-toolbar

This second image shows a <store-page> element that forms the standard base for all pages in our hypothetical online store. This element subclasses (extends) the general-purpose <page-with-toolbar> element above, so it automatically picks up the structure defined by that element and the fancy toolbar behavior. The designer of the store app can fill in some of that structure with elements that should be visible on every page in the store, such as a Home button and the story name. That is, the designer can partially fill in the slots defined by the base class: after adding the standard elements they want on every page, they can define new slots that can be filled in by instances or subclasses. The designer can also add visual styling and any behavior that should be available on every page in the app. When complete, this page both extends the above element, and is itself extensible. The element is specific to this company, but could be used by any team at the company working on their online store.

Page Template 3
A product-page partially fills a store-page

The third image shows a <product-page> element. This extends the <store-page> element above to create a template for any page specifically in the app’s Products area. It fills in the toolbar slot with buttons that are only available on product pages. It also partially fills in the main content slot with a header for the product name. Finally, it adds any styling and behavior shared only by pages in the Products area. This product page element is still extensible, but an increasing portion of its interface and behavior are constrained.

Page Template 4
A completed instance of product-page

Finally, we have an example of a filled-in <product-page> element. Presumably the app fills in the page by obtaining product data and used that to populate various elements on the page (e.g., using data binding). Now the whole page has been filled in. By factoring our app’s design this way, we’ve created a good separation of concerns. The <page-with-toolbar> element doesn’t have to know anything about online stores. Conversely, the <store-page> element doesn’t have to know anything fancy toolbar behavior. The <product-page> designers don’t even need to know where the toolbar behavior comes from — all they need to know is that they get it for free. If the team at the company that owns the <store-page> element later decides to change the toolbar behavior, they can do so without the people who own the <product-page> element needing to do anything.

How does this work?

Until recently, it wasn’t possible for a custom element to fill in slots defined by a base class this way. An element’s template could contain a <shadow> element to ask its base class to render its stuff, but there wasn’t an easy way to pass content to the base class. Over the past couple of months, the Blink folks working on Shadow DOM features have just addressed this shortcoming with a new feature in the Shadow DOM spec and its Blink implementation. Technically speaking, the spec now allows a custom element to distribute nodes into a <shadow> insertion point and then reproject those nodes into an older shadow root. To see an example of how this works, see the live demo. At the time of this post, you’ll need to use Google Canary. You’ll also need to open chrome://flags and check “Enable experimental Web Platform features”. But this feature will likely make its way into production Chrome in the not-so-distant future, and get polyfilled by the Polymer project for other browsers. You can look through the code for the complete story, but the gist is this: if your element puts stuff inside a <shadow>, then that stuff will be passed to the base class as content. In our <page-with-toolbar> example element, the template contains a bit for the toolbar that looks like this:

<polymer-element name=”page-with-toolbar”>
<template>
  …
  <div id=”toolbar”>
    <content select=”.toolbar”></content>
  </div>
  …
</template>
</polymer-element>
That <content select=”.toolbar”> bit creates a slot that can be filled in by instances — or by subclasses. When our <store-page> element subclasses <page-with-toolbar>, it fills in that slot:
<polymer-element name=”store-page” extends=”page-with-toolbar”>
<template>
  <shadow>
    <span class=”toolbar”>
      <button>Home</button>
      <content select=”.toolbar”></content>
    </span>
    …
  </shadow>
</template>
</polymer-element>

Everything inside the store-page’s <shadow> will look to the page-with-toolbar base class like regular content. The page-with-toolbar’s toolbar slot will grab the span with class=”toolbar”, so the store-page’s Home button ends up in the toolbar. This lets store-page fill in the toolbar slot defined by page-with-toolbar. So that store-page itself can be extended, it in turn redefines that toolbar slot. Any toolbar buttons defined by subclasses of store-page (like the Add to Cart and Buy Now buttons in our product-page example) will get picked up by store-page’s toolbar slot, which is nestled inside page-with-toolbar’s toolbar slot.

Conclusion

Sometimes tiny differences in fundamental features, like this refinement to the <shadow> behavior, can open up new realms of possibility. While it doesn’t look like much, when combined with subclassing, you’ve just been given a powerful new tool for creating custom web elements. You’ll be able to create a wide range of new general-purpose elements that can be filled in by other people to suit their needs, and you’ll be able to fill in general-purpose elements created by others to suit your own needs. This is a huge step towards a vibrant ecosystem of web user interface components.

Beyond the expanded capabilities enabled here, I’m personally excited to see this change because I’ve been advocating for it for so long. I made a pitch for this on a visit to Google back in May 2012, and have promoted the idea in various forums since then. Other people like Scott Miles at Google also lobbied for the same thing. Special thanks are owed to Scott and to Dominic Cooney for contributing their own weight behind this idea and building the momentum required to make it happen; to Blink developer Hayato Ito for his work updating the spec and implementing the feature in Blink; and to Dimitri Glazkov for his careful oversight of the Shadow DOM spec. This is one spec change that was totally worth the trouble!

Amazon: Please make better use of cover art to improve the ebook reading experience

As we pass through the transition from paper to electronic books, the humble book cover seems to have been dropped from important roles in the reading experience. I’m generally a huge fan of Amazon’s various Kindle devices and apps, and love the convenience that goes with them. But I’m finding some aspects of the current Kindle reading experience leave me cold, and make recalling a book harder than it should be.

We usually don’t think much about the covers of the books we’re reading, but each time you reach for a paper copy of a book, you have a chance to see a cover:

Paper Book Cover.jpg

This cover is hard at work. Before you’ve even cracked the book, the art and typography have played a subtle but useful role in setting the mood for the reading experience. Yes, the cover is serving as advertising, but it’s also an earnest attempt to visually establish the tone of what follows. Details such font choice, text size, color palette, image content, and composition, all contribute to provoking an emotional shift before you’ve even reached the primary content. In this light, a cover is something like a movie’s opening credits. In both cases, subtracting the aesthetic treatment leaves behind bare content that has to work harder to make an emotional impact.

More lastingly, the cover helps to repeatedly connect the book’s title, author, and content in your brain. During the course of reading a book, you likely see its cover numerous times (even if the cover’s only facing up half the time). I’d hazard that the cover for a typical paper novel creates something on the order of 20–40 visual impressions for the average reader between the time they see it in a store and the time they put that book out of sight.

In contrast, let’s quickly consider the use of book cover art in Amazon ebooks. When you buy a book on Amazon’s Kindle store, you can see a small thumbnail of the cover art:

Amazon Search Results.png

You can also see a book’s thumbnail in a device or app’s the Library view. But when you tap on a book to open it, you’re brought straight to the first page of text:

Kindle Book First Page.PNG

Jumping to the first page of text seems really efficient — but by skipping the cover, some things are lost. The title is presented here, but in such a subdued way that it’s easy to overlook. The author’s name isn’t even shown in portrait view. (You have to rotate the presentation to landscape, two-column view for that.) And, once you’ve begun a book, when you return to the Kindle app or device again, you’ll jump straight back to the page you were on — skipping even the small cover art thumbnail in the Library view.

The digital cover art is typically still there in the ebook content; it’s just not shown to you by default. And if you explicitly do view the cover, you will see an odd thing: the cover art presented as an image sitting on one of the book’s pages, instead of a cover that’s the same size as a page. This makes the cover feel less like a cover, and even less important than the user interface is already treating it.

Kindle Book Cover.png

Overall, I think Amazon’s doing an amazing job with ebooks. I do think the cover art could be handled more effectively. As it stands, you can lose out on quite a bit as a reader of an ebook:

Curiously, Kindle devices do show book covers, but for the wrong book. When you turn off the device, you’ll get an ad for some book you don’t yet own. I appreciate Amazon’s business need to sell more books, but this feels rather pathetic. I’ve never personally found any of these recommendations useful, and in any event I already have many ways — and better ways — to find recommendations when I visit the Amazon site. Moreover, this advertising makes the reading experience so haphazard. Because I get a different book cover each time I turn off a Kindle device, the lack of persistence makes it even harder to appreciate a multi-day reading process as a coherent experience.

What might work better? I’m sure the Kindle designers have already given this a lot of thought. I’m not an expert in ebook user interfaces, just a reader who’s been feeling underserved by the current experience, but I think it might be reasonable for the Kindle apps and devices to:

  1. Flash the book’s cover for second when opening a book for the first time.
  2. Flash the book’s cover for some shorter time (half a second?) when re-opening a book.
  3. Skip this cover display if the user goes away and then returns to a book within some short interval, say, less than an hour. If they’ve just flipped away to check something and come right back, even a short delay might feel obtrusive.
  4. Let the user turn off this cover behavior through an option if they’re really obsessed with getting that second back.
  5. On the Kindle devices, the cover of the current book should be shown when the device is off. Again, if the user really wants to hide which book they’re reading, perhaps the existing behavior could be retained as an option.

What has your experience been? If you know anyone at Amazon who’s in a position to reconsider the current handling of cover art, I’d love it if you could please point them at these suggestions.

Polymer list box and combo box elements

The updated Quetzal home page shows off a handful of new elements ported from QuickUI:

These elements still need more work. For example, the combo box needs a stock mobile variant in which the element can fill the screen when making a selection to provide bigger hit targets and maximize the number of visible list choices. Also, at the moment simply tapping a list box element causes the Android Chrome browser to crash. This makes it somewhat hard to debug. :( Nevertheless, I think these element demonstrate that a good set of UI base classes will make it much easier to create custom UI designs as web components take hold.

Quetzal, take 2: creating general-purpose UI components as Polymer elements

Just an update to the experimental Quetzal project I posted about last month. I’ve learned quite a bit, and have changed course on two significant points, and thought I’d share a bit about my experiences with others who might be contemplating the creation of a framework or UI component library on top of web components.

A limitation of the current web component architecture

So far, the greatest challenge in replicating the range of expression in QuickUI’s UI components has been the inability to easily define HTML custom element subclasses that can fill in base class insertion points. To their credit, Google’s Blink (rendering engine) and Polymer (web component framework) teams have been responsive on that point. In response to a Polymer discussion board thread related to that post, a bug has been filed to allow one to distribute content nodes into a <shadow> insertion point. Unless you’re already experimenting with Shadow DOM, this entire issue undoubtedly seems quite arcane, but rest assured, fixing this one problem would open up a lot of important new territory. I’m sincerely hoping this proposal is adopted. In the meantime, I’ve been using a workaround to simulate the effects of that proposal. That unfortunately broke in a recent Polymer update, but such setbacks are to be expected when building on shifting sand.

Trying Polymer elements

I’ve spent some time experimenting with Polymer’s own element layer, and last month decided to try adopting it. My first cut at creating custom elements for Quetzal was based directly on Polymer’s lower levels, which take care of polyfilling (emulating) various web component standards. I’m now trying to use the higher-level Polymer elements layer, which provides a richer framework for creating custom elements, and adds a number of features to simplify common component tasks. These features are not part of any web component standard, but by virtue of being done by Google, will nevertheless probably become a common feature of the web component landscape. There are still a number of QuickUI features that have no parallel in standard web components or Polymer elements, but most of those missing features appear to be things which I could implement on top of Polymer elements. For example, a <quetzal-element> base class could provide those missing features, making it easy for new element classes to obtain them. Aside from the critical limitation mentioned above, it now appears to me that most (hopefully, all) of QuickUI could likely be implemented as Polymer elements. With that change, the latest Quetzal iteration recreates a handful of QuickUI Catalog elements as Polymer elements. So far, this approach feels acceptable, and it would obviously be a big advantage to leave most of the heavy lifting to the Polymer team, and focus on actually creating new custom elements. Some notes on switching to Polymer elements:

Going back to plain JavaScript

Switching the top-level component container to HTML instead of script has also prompted me to give up CoffeeScript, at least for now. I actually tried using a combination of CoffeeScript and HTML, but it felt like I was working against the grain, and I ended up giving up on that approach. Going from CoffeeScript back to plain JavaScript is an excruciating experience. Oliver Wendell Holmes said, “Man’s mind, once stretched by a new idea, never regains its original dimensions.” I think the programming language analogue here is: once your brain has been expanded by a language that lets you more clearly express your intensions, trying to cram your brain back into the tiny box of a less expressive language is unbelievably painful. Every single time I have to write a JavaScript loop instead of a CoffeeScript list comprehension, or type “function() {}.bind(this)” instead of just “=>”, I physically wince a bit. JavaScript just feels gross, it looks gross, it is gross. That said, JavaScript is the standard. One thing I’ve learned from QuickUI is that if you’re trying to build a community around a common library, creating that library in a programming language with a narrow audience dramatically limits the rate at which you can grow. One commenter named “jokester” offered on my original Quetzal post: “I’ll unfortunately not contribute to a project coded in CoffeeScript.” Regardless of the advantages I believe CoffeeScript offers to developers, I’d rather allow orders of magnitude more people to contribute in the standard JavaScript language they’re already proficient in. Anyway, that’s about the state of things. This Quetzal project is still just an experiment, and doesn’t do much useful yet, but it’s proving a good way to learn.

If we created an open library of web components for all general-purpose UI patterns, how many would there be?

Wouldn’t it incredibly helpful if we had a library of components providing solid implementations for all the common, general-purpose, well-designed user interface patterns found in mobile and web apps? In such a library, how many components would there even be?

Regardless of the exact number, I think it’s clear that a comprehensive set of such patterns would be much larger than what’s available in most UI component libraries. Why is that are most existing UI libraries so small?

There are a few different kinds of UI libraries; let’s look at each in turn.

Operating system UI libraries

Every software operating system (Windows, OS X, Android, iOS, etc.) offers a library of user interface components. These help the platform’s developers be more efficient — but more critically, these libraries establish the visual and behavior language for their respective platforms. That is, they provide sufficient components such that native and third-party apps can present customers a reasonably consistent user experience.

OS UI libraries usually aren’t that big, though, often something in the neighborhood of 20–40 components. These include components for tried-and-true UI patterns: check boxes, radio buttons, combo boxes, tabs, menu bars, sliders, progress indicators, and so on.

But OS UI libraries seldom go far beyond that. Once the platform has been established, the platform vendor has little incentive to invest more work in their platform’s UI component library. When my startup began working on an iOS app, for example, I was stunned to discover just how few of the conventions of that platform were directly facilitated by iOS itself.

Even when an innovation such as, say, pull-to-refresh emerges in a mobile app like Tweetie and is widely emulated to the point where it becomes a de facto mobile UI standard, the UI innovation rarely makes it back into the platform itself. If it does make it into the platform, that step usually takes a very long time. Tweetie came out in 2008. Apple finally added UIRefreshControl to iOS 6 in 2012 — an eon later in mobile Internet time.

Another reason why OS libraries may have been so limited historically is that theming native UI components has been hard. Many operating systems conflate UI component appearance with component behavior, so it’s impossible (or hard) to get something that behaves just like a standard toolbar (with docking, etc.), but looks significantly different. And once you get much more complex than, say, a text box, a designer wants more control over visual appearance. To get a visually distinct result, the developer usually have to build something from scratch. The web has an advantage here with CSS, which helps separate presentation from structure and behavior. So you’d think web UI libraries would be bigger — but they’re usually not.

General-purpose web UI libraries

Web UI libraries (e.g., jQuery UI) operate under different constraints. They’re not really focused on ensuring a consistent user experience; even if a library is pretty successful, it’s still unlikely to significantly impact the user experience of the web at large. Rather, the primary goal of most web UI libraries is increasing developer efficiency. Devs don’t want to spend time rewriting modal dialog logic that’s been written many times before; a library providing a pre-authored dialog component can help them create dialogs more quickly.

Curiously, most web UI libraries still still end up with about the same number of 20–40 components as platform libraries. Possible explanations:

The answer may be some combination of these factors, but that doesn’t make the result any more satisfying. It’s still frustrating that no open web UI library is really comprehensive. The last three points, in particular, all apply equally well to any open web library operating below the level of the visible UI, and many of those have grown quite large.

Framework sample UI libraries

Some web UI libraries exist for a different reason: to provide samples of components which can be built with a given web framework. Components in such libraries effectively serve as framework documentation, and also as test cases for the framework. Their ability to simply function is what ensures other devs can build interesting, functioning components with the framework. While a few people may find the components interesting to use in their own right, that’s not really their main purpose.

To these ends, sample components tend to be somewhat specialized in their purpose. The trouble with creatint really good general-purpose UI components as sample is that such components are often fiendishly complex under the hood. They must exhaustively cover a wide range of configurations and edge cases, and such complexity can obscure or confuse the use of the underlying framework, which is the primary goal of the library. The result is that sample components tend to look visually interesting, but often aren’t directly reusable.

In any event, here again we see a fairly small number of components. Once the framework developers have delivered 10–20 examples, they may have already achieved good coverage of the framework’s features and provided ample sample code, so there’s little incentive to invest in creating more components.

Why can’t we just do all the common UI patterns?

I think a compelling criteria for a open web UI library would be to say: "This library tries to provide all the UI patterns in widespread use on the web." That is, if a UI pattern appears in some reasonably interesting percentage of popular apps, then the library should provide a component delivering a solid baseline implementation of that UI pattern.

A comprehensive web UI component library sounds ambitious, but it’s not crazy. It's probably only an order of magnitude bigger than the tens of components in the OS and web UI libraries described above.

When I first started on the QuickUI Catalog, my hope was to eventually create exactly that: a home for solid implementations of all common UI patterns. For a while now I’ve been looking at the emerging collection of web component technology standards to see if they can provide a good substrate for such a collection. The technologies are still coming together, but it now appears likely that a comprehensive UI library could indeed be delivered as standard web components. In the short term at least, such a library would need to be augmented with Google’s innovative and compelling Polymer project, which allows new web technologies like custom elements to function on older browsers.

Compiling a comprehensive list of UI patterns

To help make the case a comprehensive UI library is achievable, I’ve been compiling a list of every UI pattern I can find that seems common, general-purpose, and well-designed. Some notes on these criteria:

Beyond conventional web UI patterns, I want this list to include mobile UI patterns, even those typically implemented in native code. My belief is that a mobile web app should be able to do anything a native mobile app can do, so I’d prefer to include (native) mobile UI patterns from the start.

This list comes from direct experience, as well as combing through various collections of UI patterns on the web. It’s by no means complete, but I think it can already serve to help estimate the initial size of such a library.

Without further ado, the list currently stands as follows…

An initial list of common, general-purpose web UI patterns

  1. Accordion. A list that can have a single item or multiple items expanded to show more detail.
  2. Alphabetic indices. Renders the characters in a culture’s alphabet in standard order (e.g., as a vertical or horizontal strip). If supplied with a set of strings, the UI will disable those characters which are not found as the initial character of any string.
  3. Async operation button. A button whose caption changes to reflect an operation in progress (e.g., changing from “Sign In” to “Signing In…”) until the operation completes.
  4. Auto-complete. A text input field that helps the user quickly enter strings from a known list.
  5. Auto-format. Applies a collection of heuristics for formatting text: adding smart quotes, converts double hyphens to endashes, etc.
  6. Auto-size text box. A text area that expands to contain its text.
  7. Backdrop. Shows a background region of non-interactive elements behind the region’s main contents.
  8. Blog. Shows some or all of the entries in the indicated RSS feed.
  9. Blog headlines. Shows the headlines of some or all of the entries in the indicated RSS feed as links to the full articles.
  10. Breadcrumb bar. Indicates the user’s position in a navigational hierarchy.
  11. Browser specific. Conditionally shows contents based on the browser being used and/or whether the current browser supports a given feature.
  12. Calendar day. Shows a single day in a calendar.
  13. Calendar month navigator. Lets the user select a date, typically in the near future, by navigating through calendar months.
  14. Calendar month. Shows a single month from a calendar as a standard seven-column table, taking care to reflect a given culture’s preference for the first day of the week.
  15. Calendar months. Shows multiple months from a calendar.
  16. Calendar week. Shows a single week from a calendar as seven days in a row, taking care to reflect a given culture’s preference for the first day of the week.
  17. Carousel. Lets user navigate laterally between panels with a sliding transition.
  18. Central column. A region whose main central column is fixed in width, and horizontally centered with respect to the viewport.
  19. Checked list box. A list box showing a check box next to each item; the user can create a multiple selection by checking the boxes.
  20. Close box. A platform-sensitive representation of a button that will close the current dialog or window.
  21. Closeable panel. Shows information (e.g., a warning, or the result of a completed operation) that can be dismissed to remove the panel from the visible page.
  22. Collapsible panel. A region that can be toggled between collapsed and expanded states.
  23. Color wheel. Lets the user select a color in a variety of color spaces.
  24. Combed text box. A text box sporting tick marks or vertical lines to visually indicate how many characters should be entered.
  25. Content grid. A region which provides a sense of visual organization by dividing its width into a number of columns (e.g., 12) which can be variably spanned by content panels.
  26. Content transition. When supplied with new content, transitions from the existing content to the new content using a common animated transition (fade, fade through black, slide, wipe, etc.)
  27. Content with banner(s), such as toolbar (on top) or status bar (on the bottom).
  28. Content with sidebar(s) on the left and/or right side.
  29. Countdown clock. Represents the time (in days/hours/etc.) until a given point in time.
  30. Credit card. Asks the user to supply a credit card and performs initial validation.
  31. Date combo box. Lets the user type a date or choose one from a dropdown calendar.
  32. Date range calendar. Lets the user select a date range, typically in the near future.
  33. Date text box. Lets the user type a date in several culture-specific formats.
  34. Days of week. Shows the names of the seven days of the week using a given culture’s day names in short/abbreviated/full format.
  35. Delimited list. A list of items interspersed with a decorative element (bullet, vertical bar, etc.) for cleaner delineation.
  36. Device specific. Conditionally shows contents based on the type of device being used and/or device capabilities.
  37. Dialog. A popup window, typically modal.
  38. Editable in place. An element that supports its own in situ editing.
  39. Editable text. A piece of static text data which can be clicked to produce a text box that can then be used to edit the data.
  40. Expandable summary. A block of content with a “More” link at bottom; clicking this reveals the remainder of the content.
  41. Fader. Instead of clipping content, it fades out content on the right or bottom edge to suggest additional content exists but could not fit.
  42. File uploader. Allows the user to click or drag-and-drop to supply a single file for upload.
  43. Full screen region. A region supporting a mode in which the region will expand to fill the entire screen.
  44. Full size-able. A region which fills the viewport, independent of the size of the page content.
  45. Infinite list. A list which asynchronously loads additional contents as the user scrolls.
  46. Labeled input. An HTML input control (generally a check box or radio button) with an associated clickable label.
  47. Lateral navigator. A panel with previous and next arrows on either side, allowing the user to navigate laterally through a discrete set of states.
  48. Link list. Uses a platform-sensitive presentation of a set of links (or items that behave like links).
  49. List. Renders each item in a heterogenous set as a vertically stacked set of elements.
  50. List box. A list that supports single selection, including keyboard navigation.
  51. List combo box. A combo box which presents its choices as a dropdown list.
  52. List with detail pane. A list box showing a set of items, paired with a means of showing properties of the selected item. These properties are either a pane (usually to the right) on desktop or tablet devices, or a separate page on mobile devices with smaller screens.
  53. Log. Displays a growing text log showing, for example, the output of an ongoing process.
  54. Markdown. Renders a block of Markdown as rich text.
  55. Masked text. A text box which only accepts specified input characters.
  56. Menu bar. A row of menus.
  57. Menu item. A command in a menu.
  58. Menu separator. A line separating commands in a menu.
  59. Menu. A popup menu, often in a menu bar.
  60. Mobile date/time picker. Platform-sensitive collection of elements which emulate the platform’s native date/time picker.
  61. Modes. Shows exactly one item at a time.
  62. Month and year. Shows the month and year of a given date in a format appropriate for a given culture.
  63. Month name. Shows a given culture’s name for the month of a given date.
  64. Multi list box. A list that supports multiple selection, including keyboard navigation.
  65. Multiple file uploader. Allows the user to click or drag-and-drop to supply multiple files for upload.
  66. Number with units. Facilitates entry of a number with units (e.g., “10 in.”, “5 minutes”, “60 kg”).
  67. Overlay. A transparent or semi-transparent blanket over the entire page which absorbs interactions outside a modal element.
  68. Packed columns. Packs its children into a dynamic number of columns of roughly equal height (e.g., see the Pinterest home page).
  69. Page number navigator. Indicates the number of pages, e.g. of search results, and also allows navigation to a particular page of results.
  70. Palette window. A persistent set of tools adjacent to, or superimposed on, a work surface, providing tools for manipulating the information on the surface.
  71. Panel with overflow. A panel fixed in width or height which allows any items which don't fit to overflow into a dropdown menu.
  72. Password strength assessment. Provides a rough assessment of the strength of a possible password.
  73. Persistent header. A scrolling list in which the header for the group of items currently at the top of the visible list remains visible until the user scrolls the next group to the top. At this point, the new group header pushes the previous group header out of sight.
  74. Persistent panel. A panel whose contents will bump up against the top or bottom of a scrolling parent so as to remain always visible.
  75. Person name. A set of input elements for obtaining all or part of a person’s name.
  76. Phone number. Allows entry of a phone number for a single locale or a range of global locales.
  77. Popout. An item that can expand (e.g., on hover) without affecting the visual position of surrounding items.
  78. Popup button. A button that produces a popup when clicked.
  79. Popup source. An element which invokes a popup.
  80. Popup. An element which temporarily pops up over other things. Can be modal or modeless.
  81. Postal address. Allows entry of a postal address for a single locale or a range of global locales.
  82. Postal code. Allows entry of a postal code for a single locale or a range of global locales.
  83. Process steps. Shows a numbered list of steps in a task, disabling steps which are not yet available.
  84. Progress bar. Indicates the fraction of an operation which has been completed.
  85. Progress indicator. Platform-sensitive representation of an ongoing operation whose expected duration is unknown.
  86. Pull to refresh. A region which the user can pull down to reveal a platform-sensitive “Pull to refresh” and “Loading” representation.
  87. Radio button list. A list box showing a radio button next to each item; an alternative way to represent selection in a single-selection list.
  88. Repeater. Creates a certain number of instances of another element class.
  89. Ribbon. A space-sensitive presentation of a set of commands.
  90. Rich text editor. Supports the basics: bold, italic, insert link, etc.
  91. Rotating panels with dots. Rotates (once or indefinitely) through a sequence of horizontally-arranged pages, usually to add visual interest to a home page.
  92. Search box. A text box with standard decorations (magnifying class, customizable “Search” hint) to suggest a search field.
  93. Sequence navigator. A lateral navigator that lets the user navigate left and right through an ordered sequence of items.
  94. Slider. Accepts a discrete number in a constrained range.
  95. Sliding panels with dots. Sliding panels which add a series of dots to navigate its contents.
  96. Sliding panels. Arranges a set of items on a horizontally sliding strip; only one item can be fully seen at any time.
  97. Spin box. Accepts a discrete number, potentially in a constrained range.
  98. Splitter. A movable line sitting between two panels which can be dragged to change their relative sizes.
  99. Sprite. Shows a single image at a time from a strip or grid of images.
  100. Stacked navigation pages. As the user navigates deeper in an app, a small residual portion of the previous page remains visible (typically on the left); the user can swipe away the top page to navigate back to an earlier point.
  101. Star rating. Lets the user rate something (a restaurant, product, etc.) using the conventional star system.
  102. Tab strip. A set of tab buttons, typically used to navigate among tabbed pages presenting different content, but which can also be used, for example, to apply one of a set of filters to a results list.
  103. Tab. A tabbed page which can be hosted in a set of tabs.
  104. Tabs. A set of pages which can be navigated by a set of tab buttons across the top.
  105. Tag text box. Tokenizes text input into a set of tags, and provides auto-completion against a set of existing tags.
  106. Text box with button. A control with a content area (usually some form of text box) and an associated button (“Go”, “Submit”, etc.).
  107. Text condenser. Switches to a condensed font when necessary to squeeze in more text.
  108. Time combo box. Lets the user type a time or choose one from a dropdown time picker.
  109. Timeline. Positions items on a horizontal time axis.
  110. Toggle button. A button the user can click to toggle its selected state.
  111. ToolTip. A popup that appears when hovering the mouse over another element, providing more detail about that element.
  112. Transient message. A message which briefly appears on a page before automatically disappearing. Typically used to display feedback after an operation has completed (e.g., “Message sent”) without requiring user acknowledgement.
  113. Tree view. Visually renders a hierarchy of items as a tree whose branches can be expanded and collapsed.
  114. Validating text box. Verifies that text box content meets some criteria.
  115. Vote up/down. A pair of buttons to vote something up or down; can reflect the current state of the user’s vote.
  116. Wizard. Steps the user through a task through a small set of pages.

This seems totally doable

Okay, so there’s a little over 100 UI patterns in this list, suggesting that a comprehensive, general-purpose web UI library would contain a number of components of that order. (Some patterns may require implementation as multiple components.) You and I will likely disagree about the correct decomposition of a given UI into a set of patterns, or about the best way to implement a pattern with components, or about what everything should be called, but I’m guessing that debate won’t change the size of the list much.

More eyes on the problem — more people looking for common, general-purpose UI components — would certainly increase the size of the list, but probably not too much. For argument’s sake, let’s assume the list above captures little more than half of the general-purpose UI components the library should ultimately deliver. That still puts the list at only 200 components. My instinct is that any organizational strategy that can produce a library of 100 components can also produce 200 components.

There’s clearly some kind of existing inflection point when a library reaches approximately 40 components, or else we would see more libraries with more components. But I’m hoping the next inflection point won’t be reached until a much higher number of components. Specifically, it’s my contention that the apparent barrier of 40 components in a UI library can be breached with network effects.

That is, a key limiting factor to date which has prevent a comprehensive UI library (or marketplace, or ecosystem, whatever) has been the inability for one group to benefit from another group’s UI work. I hope web components, seeded with efforts like Polymer, will change this dynamic, enabling us to blow through this barrier and create easily sharable solutions to common UI patterns. As I’ve often said before, that will allow us to stop burning so much time reinventing things, and focus more of our precious time on delivering value unique to our apps.

Puzzle: Define HTML custom element subclasses that can fill in base class insertion points

This post presents a little web component architectural puzzle which I’ve come across in the early stages of creating Quetzal. The puzzle deals with how Quetzal should best deliver an important component service on an HTML custom element substrate, and relates specifically to subclassing semantics. Any suggestions or comments would be much appreciated.

Background on the puzzle

Quetzal is an attempt to deliver key features of the QuickUI component model in HTML custom elements. One such feature is that an element subclass should be able to easily populate a slot (insertion points, in HTML parlance) defined by a base class. In practice, there are many situations in which you want to be able to say, “This new UI component should be just like that existing UI component, only with some stuff pre-filled in.” For example:

Well-defined subclassing semantics are essential for creating a UI component library with a good separation of concerns. If you look at the class hierarchy depicted for DateComboBox (above), you’ll get a sense of the degree to which it’s possible to portion out specific roles to a small constellation of classes, such that each class can focus on just doing one thing really well. I’m hoping that it is possible to take advantage of such subclassing semantics in HTML custom elements — but it’s not proving to be particularly easy.

The puzzle

The puzzle is to come up with an architecture for custom element subclasses that meets the following design criteria:

  1. An instance of a subclass is a proper instance of its base class. All the normal JavaScript stuff should work: property/method access should go up the prototype chain, and a subclass instance should report that it is an “instanceof” the base class. By default, the HTML <element> syntax permits an “extends” attribute to identify a base class, but a purely script-based solution that sets up the class hierarchy correctly is equally valid.
  2. A subclass can put stuff into an insertion point defined by the base class. That is, the subclass can fill in a slot (or slots) defined by a base class. In turn, the subclass should be able to redefine such an insertion point so that the subclass itself can be subclassed.
  3. Unless overridden, all base class behavior should function properly in an instance of the subclass. E.g., if the base class wires up an event handler, then this works as expected for subclass instances too.
  4. Base class properties/methods can be overridden by the subclass. A subclass’ property/method implementation should be able to invoke the base class’ implementation by whatever language means are necessary. (CoffeeScript provides sugar for this; plain JavaScript developers have alternate ways of achieving the same result.)
  5. The base class can be any HTML custom element class; the base class author shouldn’t have to do special work a priori to enable this kind of subclassing. This ensures a Quetzal author can always use someone else’s element class as a base class — even if that other person has never heard of Quetzal.

A successful solution needs to meet all five of these criteria. So far, the approaches I’ve tried can satisfy at most four at a time.

Example

Let’s walk through a example from the small set of custom elements currently shown on the Quetzal home page. This set includes a base element class called quetzal-button that shows its content inside a button, and another element class called icon-button which adds an icon to the plain-button content. For clarity, here let’s just call that base class plain-button instead of quetzal-button, since the following source won’t actually involve Quetzal. In any event, we want markup like this:

<plain-button>Plain button</plain-button>
<icon-button icon="document.png">Icon button</icon-button>

… to produce something like this:

Buttons

Where icon-button is reusing all the styling and behavior from plain-button; it’s not duplicating the styling and behavior. The challenge is to create the icon-button element so it both inherits (in the class sense) from plain-button and extends the visual representation of plain-button.

A partial solution to filling in base class insertion points

The first challenge is: how can icon-button add elements to the content shown by plain-button? Some approaches:

  1. We could try to apply the template for both plain-button and icon-button to the same host element. The Shadow DOM spec supports multiple shadow trees attached to the same host. This feature alone is insufficient for the above example. Unless one shadow tree takes care to incorporate the other somehow, the most recently-added shadow subtree wins. If plain-button renders last, we get a button but no icon; if icon-button renders last, we get an icon but no button.
  2. We can include a <shadow> element in the template for icon-button, and ensure plain-button renders its shadow subtree first. The <shadow> element allows icon-button to effectively include the representation for plain-button. Unfortunately, this inclusion effectively wraps the base representation, rather than filling it in. An icon-button does get a button and an icon, but the icon and content render outside an empty button: shadow
  3. We can have icon-button create an instance of its own base class, then have that instance contain the icon and the icon-button’s own content. (This approach is based on a suggestion from Shadow DOM spec author Dimitri Glazkov.)

Approach #3 does what we want from a strictly visual perspective. (Behavior is a separate matter.) The source for a Polymer element version of this approach looks something like:

<element name="plain-button" extends="button">
    <template>
        <button>
            <content></content>
        </button>
    </template>
    …
</element>

<element name="icon-button" extends="plain-button" attributes="icon"> <template> <plain-button> <img src="{{icon}}"> <content></content> </plain-button> </template> … </element>

See a live example of this. It should work in most browsers, but use Chrome if you want to see it working with real Shadow DOM. (Note: a Chrome bug prevents the buttons from responding correctly to mouse interactions. The buttons do receive mouse events, but for now it just doesn’t look that way.)

If you open the example and inspect it in Chrome dev tools, you’ll see that an icon-button has a shadow subtree containing a plain-button; the plain-button contains its own shadow subtree. Content of an <icon-button> element is therefore distributed twice: once into the <plain-button> element, and then again into the native <button> element. The ability of Shadow DOM to distribute nodes multiple times is called reprojection. (Or, at least, it meets the definition of reprojection as I understand it: “when an insertion point is a child node of another shadow host”.)

Inheritance versus containment

Unfortunately, while this approach looks right, it doesn’t behave quite right. An icon-button here is not only an instance of plain-button, it also contains a plain-button. That’s problematic.

  1. When icon-button instantiates its inner plain-button, the inner button has no way to know its relationship to icon-button. Among other things, this means icon-button can’t easily override behavior defined by plain-button (one of the design criteria above). In the JS Bin example, you can turn on the Console pane to see debug output. The plain-button element class defines a readyCallback (in Polymer, “ready”) that invokes a base class method called log(). The icon-button class overrides that log() method, but because the inner plain-button is just that — a plain-button — its readyCallback will invoke the base plain-button implementation of log() instead of icon-button’s specialized log() implementation. Running the demo invokes log() four times, when: 1) creating an instance of plain-button to use as the prototype for icon-button, 2) creating the visible plain-button with text “Plain button”, 3) creating the inner plain-button used by the visible icon-button, and 4) creating the visible icon-button with text “Icon button”. It’s #3 and #4 together that are the problem: what we really wanted to do is invoke icon-button’s log() implementation once.
  2. Automatic element references (a la Polymer, and also in Quetzal) aren’t inherited by default. If plain-button defines an element with id #foo, then plain-button methods can access that element via the automatic reference this.$.foo. Similarly, we want an icon-button to have access to the same reference this.$.foo defined by the base class. (Or, at least, we can debate whether such automatic references should be treated as “private” or “protected”, but it seems to me that “protected” would be useful.) It’s possible to work around this particular issue for a known set of frameworks — that is, Quetzal could workaround this problem for its own classes, and perhaps for those defined by Polymer — but it wouldn’t work in the general case of an unknown framework.
  3. It’s easy to end up in situations where both icon-button and plain-button are duplicating work. Suppose an icon-button method invokes a super-method of the same name defined by plain-button, and suppose the base implementation of that method performs expensive work or obtains a reference to some resource. When the inner plain-button is instantiated, it might do that work — and then the same work or allocation might be repeated by the outer icon-button when it invokes the super-method. Conventions could be established to avoid this, but it would complicate otherwise simple situations, and again make it hard to use subclass elements from other frameworks.
  4. As a common case of the above point, if the inner plain-button wires up an event handler, then it’s easy to end up in situations where the event is bound by both the inner plain-button and the outer icon-button. If the event bubbles up from something inside plain-button (a click on the button, say), you would end up handling the same event twice.

We could try to simplify things by just containing an plain-button, and not deriving from it. This forces us to give up one of the original design criteria outlined above: an instance of icon-button wouldn’t actually appear to be an “instanceof” plain-button. Moreover, if plain-button defined some attributes (“disabled”, say), icon-button would have to explicitly handle those too and forward their implementation to the inner plain-button.

We could have icon-button create a placeholder element (a <div>, say), create a shadow root for it, and populate that root with a copy of plain-button’s template but without actually instantiating that inner element as a real, live plain-button. This is the approach that Quetzal currently uses. It solves a number of problems, but is dependent on knowing how a given base element class works. Quetzal reaches into the base class’ implementation to obtain its template and then clones it, which might not be possible with other frameworks. This violates one of the design criteria above.

We could create a temporary instance of plain-button elsewhere, then clone just its contents into the icon-button instance. This avoids requiring detailed knowledge of what the base class is doing. But it could also result in subtle problems. E.g., the base class might not be expecting to have to serialize all its state into its shadow subtree, in which case the cloned content might not represent a coherent instance of the base class.

Looking for suggestions

This post is effectively a form of rubber duck debugging. The simple act of writing this up has forced me to better understand the problem, and led to consideration of alternate lines of attack. The puzzle remains unsolved, however. Given my understanding of custom elements, and the design criteria for the puzzle above, I’m not sure whether a solution exists.

It’s theoretically possible I’ve hit some limit in the expressiveness permitted to custom elements in their current state. Perhaps that limitation could be addressed. If not, I’d  have to write off a big chunk of the solutions used by the QuickUI Catalog and QuickUI apps, and find alternate ways of meeting the same needs.

I’m hoping, however, that I’m just missing something. If you have some passing familiarity with HTML custom elements and Shadow DOM, and have ideas about how to approach this problem within the existing technology, I’d love to hear them!

Do web component developers still need jQuery

I love you, jQuery. But maybe it’s time we started spending some time apart.

Improvements in cross-browser feature set and compatibility are reducing the need for jQuery, but more importantly, it turns out that a component-based app needs very little jQuery to begin with. These insights led to one of the first decisions I hit in starting Quetzal: should it require jQuery? The answer, so far, is no.

Since its inception in 2007, QuickUI has relied on jQuery as a crucial browser abstraction layer. Without jQuery, QuickUI would have never have come to exist. However, the QuickUI runtime itself only uses a fairly small set of core jQuery functions, and modern browsers now deliver standards-based solutions for those situations. Moreover, I’ve noticed that, when building QuickUI component-based apps, component code tends to rarely require sophisticated jQuery.

Meanwhile, the web has moved forward. The modern browsers — the latest Chrome, Safari, Mozilla, and Internet Explorer 10+ — are all much, much more consistent to develop for than browsers were six years ago. Glancing at pages on QuirksMode, one generally sees a see of green compliance, with most of the red markers of non-compliance for older versions of IE. And according to StatCounter, market shares for both IE 8 and 9 have now dropped below 10% (each), so it’s plausible for mainstream organizations to justify ignoring them.

Let’s break down the things jQuery is good at, and consider how necessary are in a web component-based application (specifically) targeting the modern browsers:

Generally speaking, in a component-based app, you want to give each component the responsibility for managing its own appearance and behavior. You don’t want code walking all over the DOM tree and mucking around with things that aren’t its direct responsibility. Instead, you talk to the component managing the part of the DOM you care about, and ask that component to manipulate the elements it directly owns. In classic object-oriented programming terms, this is an application of the Law of Demeter.

In practice, compartmentalizing things that way leaves each component doing very simple manipulations on a comparatively small set of elements: instantiating a new element; iterating over its own children; applying or removing a style; etc. If a component wants to do something more sophisticated to its internals, more likely than not the component should delegate that operation to one of its own sub-components. The component’s own need to search is limited, reducing the need for a powerful selector/traversal engine. And, given a reasonably good programming language, simple DOM manipulations can be performed effectively — and with better performance — by directly accessing the DOM API.

I’m no cross-browser DOM API expert, and I’ve only just started to try to do things without jQuery. I could easily hit a landmine tomorrow, tripping upon some cross-browser nastiness I’ve been blithely unaware of, which jQuery for years has been invisibly and reliably been protecting me from. That said, work on Quetzal is progressing fairly smoothly without jQuery, and a week or two into this project, I’m not missing most of jQuery. It would be nice to have a much smaller library of helper functions which present a more JavaScript-flavored approach to the DOM API, as in jQuery’s css(), mentioned above.

From one standpoint, you could say I’ve just traded one browser abstraction layer (jQuery) for another (Polymer’s platform.js). However, platform.js feels like a pretty different animal than jQuery:

We’ll see how the Quetzal experiment evolves, but so far, writing directly to the DOM API is working out okay.

So, jQuery, maybe we should spend some time apart. Maybe we should see some other people. It’s not you — it’s me! Don’t worry; I might miss you terribly and come running back. Or maybe we’ll just be friends.

It’s okay. We’ll always have IE6.

Quetzal: an experimental translation of the QuickUI component model to HTML custom elements

I’ve started an experiment called Quetzal that considers translating the core concepts from QuickUI to the proposed web component standards currently embodied by Polymer.

[Update June 13, 2014: The Quetzal project has grown into an open source project called Basic Web Components. Please take a look!]

While continuing working on QuickUI, I’ve been tracking the progress of the Google-led efforts on web components: custom elements, Shadow DOM, and related advances in the web platform. Those technologies address many of the same issues QuickUI addresses, so I’ve been trying to chart a path by which QuickUI and web components could co-evolve.

Until recently, those web component technologies were generally available only on Google Chrome, which means QuickUI can’t rely on them. However, since the start of the year I’ve been watching Google’s Polymer project which, among other things, offers a suite of polyfills that allows one to create and use components in the other “modern” browsers, including recent versions of Safari, Firefox, and Internet Explorer 10+. Polymer offers a fairly compelling story for using those future browser technologies today.

I’ve spent a bit of time looking at how to retrofit support for Shadow DOM and other aspects of web components into QuickUI. While that’s led to some progress, I’m not entirely sure that that’s the best approach. To ensure this is being done the best way, I’d like to try an alternative approach build from scratch directly on top of a custom element substrate. That experiment is Quetzal.

There are a number of aspects of QuickUI that I believe are quite compelling, and which are either not easily supported in the proposed web standards, or appear under-represented in the current body of web components work. My goal in Quetzal is to explore whether those aspects of QuickUI have meaning in the world of web components, and what’s the best way to bring those benefits forward. Some of those aspects of QuickUI I would very much like to see carried forward to the world of custom elements are:

The Quetzal experiment seeks to preserve the above features, while still allowing a designer or developer to create new custom elements which can interoperate with custom elements created by any other means (e.g., as Polymer elements). Some early technical decisions for Quetzal:

Quetzal isn’t ready for real use yet: it does just a few things at this stage, it’s not document, it’s buggy, it doesn’t work cross-browser (even with polyfilled custom elements), etc. But I wanted to announce the experiment now so that I can follow up here with additional posts as I go along. Work on Quetzal is generating questions I want to ask others, and to provide context for those things it’s going to be helpful to be able to reference Quetzal posts here and source code on GitHub. After exploring some ideas, Quetzal’s useful life may come to an end, or its lessons might get folded back into QuickUI, or it may evolve into a library of Polymer elements.

If you’re interested in following along, subscribe to this blog, and/or follow me on Twitter and Google+.

Cheers, Jan Miksovsky

QuickUI 0.9.4 released

This release fixes a number of small bugs in both QuickUI and the QuickUI Catalog.

The most significant change is in the Control constructor. QuickUI previously went through a lot of trouble to subclass jQuery. This code involved patching up a class when an attempt was made to instantiate it so that the result would be acceptable to jQuery. Specifically, the resulting patched-up class could be instantiated without requiring the “new” keyword. This code was quite complex and brittle, and was eventually broken by a change to the CoffeeScript 1.5 compiler. The CoffeeScript folks graciously backed out that change in CoffeeScript 1.6 so that QuickUI could continue to function.

Meanwhile, a workaround had already begun to drastically simplify the Control constructor — in exchange for dropping the ability to instantiate a control class’ constructor without the “new” keyword. As it turns out, QuickUI controls are typically instantiated via the framework itself, either declaratively through Control JSON or imperatively by invoking Control.create(). Only the framework needed to directly instantiate a control class, and so the framework source was updated to always make use of the “new” keyword.

By the time this workaround was ready for deployment, the CoffeeScript 1.6 change made that workaround unnecessary. However, because the workaround was already working, and had significantly simplified the framework source, it was decided to keep the workaround. It was probably still correct for CoffeeScript 1.6 to back out the earlier breaking change to control constructors in CS 1.5. As this experience shows, the change not only dictated what CoffeeScript developers could do, it prevented or impaired their ability to integrated with plain JavaScript libraries which made use of “other typed” constructors.

In general, despite this constructor change deep in the framework, QuickUI developers should generally observe no changes in framework behavior.

The QuickUI Catalog has a few small bug fixes, but the version number has been bumped to 0.9.4.0 to keep in sync with the new version number for QuickUI 0.9.4.

QuickUI breaks with CoffeeScript 1.5

Bad news: this week’s release of CoffeeScript 1.5 is incompatible with even the current QuickUI release, 0.9.3.

QuickUI goes through significant trouble to subclass jQuery because of jQuery’s complex constructor. jQuery depends on an unusual feature of JavaScript called an “other typed” constructor: a class constructor that returns something other than a plain instance of the class being instantiated. When the CoffeeScript project considered dropping support for such constructors, cases were made to keep that feature (see CoffeeScript issue #2359, but other people made similar cases on other issues). However, those arguments did not carry the day, and as of CoffeeScript 1.5, “other typed” constructors are rejected by the compiler. This effectively breaks the CoffeeScript source for QuickUI itself as well as for QuickUI Catalog.

Possible fixes are being investigated, but this issue runs very deep, and a number of straightforward workarounds have already been ruled out. A real fix will likely require a substantial change to the way QuickUI instantiates controls. For the time being, it is recommended that QuickUI developers use CoffeeScript 1.4.0.

UI component whiteboard talk: The Web Still Needs a Vibrant UI Ecosystem

I've been considering putting together a video screencast sharing some thoughts on web UI components, covering the case for why we need them, some limited solutions today, the prospects for the Web Components standard, and the principles behind my own work on the QuickUI web component framework. It's been my experiencing that producing even a very short video takes gobs of time, but it occurred to me that I could break up the talk into short segments, perhaps 5 minutes or less in length. As an experiment, I created this short (4 minute) intro video:

 

 

WheneverI speak in group settings, I always find myself sketching ideas on the whiteboard, so I thought that a whiteboard talk might be a reasonable format for a web video – perhaps that can strike a good balance between something that's engaging while also not incredibly time-consuming to produce. In the course of considering how to make such a whiteboard talk, I came across an interesting iPad app called Doceri that lets you project your iPad sketches onto a desktop computer. Doceri includes its own complete screencast production tool, but unfortunately the audio quality of an iPad's built-in mic isn't great, and editing on an iPad is currently cumbersome. I ended up projecting the Doceri project onto a desktop window, capturing the window contents with Camtasia, then laying down the audio narration in Camtasia and doing final editing there.

I hope you find this short video interesting. If this seems worthwhile, I might follow up with additional segments on a semi-regular schedule.

QuickUI Catalog 0.9.3.1 released

The QuickUI Catalog has been updated to version 0.9.3.1. This is a modest update in terms of functionality, but a significant milestone for the catalog — it represents the culmination of an effort to port all the Catalog controls to a combination of CoffeeScript and LESS.

The original QuickUI framework included the use of a local build tool called the QuickUI markup compiler. This compiled a markup format that was essentially HTML plus the use of custom tags. (In this, the format was remarkably similar to the spec’ed format for Web Components.) Because this format never got any traction, it was eventually deprecated, although still used for the vast majority of the Catalog controls. 2013 has begun with a major push to port all these controls to CoffeeScript for content and behavior and LESS for appearance.

Now that that port has been accomplished, it will be easier to move the Catalog forward, including the addition of new controls and some refactoring of existing ones. Along with this port, a handful of other controls were added to the Catalog:

A 2013 wall calendar optimized for project management discussions

In many project discussions, it’s been my experience that two calendar-related questions constantly arise:

  1. On what day of the week will date x fall? Example: We’d like to make our next release on or around the 15th of next month. Is that a weekend?
  2. What is the date of a given day of the week n weeks from now? Example: We usually publish releases on Thursdays. If we want to release Thursday of next week, what date is that?

For several years, I searched for a large wall calendar I could hang in meeting rooms used for project discussions, but couldn’t find anything suitable. Calendar companies still living in the dark ages make the calendar dates unnecessarily small to leave extra room for writing information directly on the calendar by hand. That’s useless to me. I don’t want to track vital project information on the physical wall of a meeting room; I want to track it online where everyone can see it. Nor does a meeting room need a calendar decorated with scenic pictures. Finally, a giant wall calendar that only shows a month at a time is too limited in scope. All I want is a wall calendar that answers the two questions above.

If you want to design a calendar with only the above two goals in mind, I think the logical conclusions are:

Since I couldn’t find a wall calendar that incorporated these principles, I put one together myself:

 

Wall Calendar 2013

 

I’ve now used such calendars for a number of years, and they work great. It’s very easy for anyone in a meeting to quickly answer the key date questions above. I also find it handy to keep one at my desk — glancing at the wall is faster than launching a calendar gadget.

Since other people like these, I thought I’d put these into the public domain. If you find them useful as is, great. Otherwise, feel free to remix to suit your own needs.

The calendars above are U.S.-centric, with the first day of the week on Sunday, and with U.S. federal holidays highlighted. A friend asked for an international English version, with the first day of the week on Monday, so I’ve also created PDF and Microsoft Word versions of that. These have no holiday highlighting.

QuickUI 0.9.3 released

This minor release is being made now because it contains a fix for the forthcoming release of jQuery 1.9. Changes:

The corresponding release of QuickUI Catalog 0.9.3 includes some minor enhancements: