Which of these month calendars looks correct to you?
One of the calendars will probably look right. The other two will just look wrong — like they’re mistakes, or maybe not even calendars. Setting aside the basics of which language the words appear in, the simple question of which day column should be first is a pretty key thing to get right in a calendar. Depending on where you live or grew up, you may prefer that the first column of a month calendar be Mondays, Sundays, or Saturdays. (It’s not completely clear to me, but it appears there may be a community of people — speakers of Dari, a dialect of Persian — who prefer that the first column be Fridays.) In some languages, you may want the order of days to go right-to-left as well, in which case you might want the first column to be the rightmost instead of the leftmost.
These are the kinds of detail that are nearly impossible for a small team to get right if they’re writing their own calendar from scratch, and yet the world is filled with proprietary date picker widgets and calendars. Even if we ignore the colossal waste of time represented by all those unnecessary reinventions of the calendar, nearly all of those calendar implementations will fail to localize basic details (such as the day shown as the first day of the week). That is, if your app is using a calendar your team wrote from scratch, there is a very good chance that a substantial number of users outside your country and language view believe your calendar is just wrong. And even if you picked up a calendar widget at some point, and it was pretty good to begin with, if you copied that code, you likely haven't picked up any of the bug fixes that were made in it since you made your copy.
This is yet another area where a broad web component ecosystem will fundamentally change things. As discussed on this blog many times before, the economics of user experience design and engineering will of course change. But it’s also the case that sharing solid user interface components will finally allow a broad swath of the software industry to finally get UI details right on tricky things like calendars.
With that goal in mind, I’ve contributed a set of calendar components to the open source Basic Web Components project. Rather than producing a monolithic monthly calendar component, these components follow the guidelines for general-purpose components. Among other things, they are factored into components that each try to do just a single thing well:
basic-calendar-day. This shows a single day in a week/month/year calendar. It has a date attribute indicating which day to show. By default, it just shows the number of that day in the month. That is, for August 1, 2014, it just shows the text “1”. That’s all it does.
basic-calendar-week. This represents a single week. It’s just a collection of 7 basic-calendar-day components whose date attributes are synced to always be one day apart. (The component takes special care to deal with things like daylight savings time changes.) Which day of the week is shown first can be changed to suit the user’s preferred location/culture (see localization, below). By default, the days are shown in a horizontal layout. This week is used in the month calendar component described below, but could also also be used in other situations, such as an infinitely-scrollable calendar.
basic-calendar-month-days. This shows the days of a single calendar month. This is constructed as set of 4 to 6 instances of basic-calendar-week. (The number varies based on the length of the month and the day of the week the month starts on.) This component does not include any headings. By default, weeks are shown in a vertical stack. This is done with default styling using a CSS display: table-row-group rule, so that headings for the day columns can easily be added and lined up correctly.
basic-days-of-week. This just shows the names for the days of the week in a given language (see localization, below). The standard CSS styling for this has display: table-row-group, so it can easily be matched up with a table-row or table-row-group like basic-calendar-month-days. This component (and some of the others here) doesn’t have the word “calendar” in its component name because there might be some situations in which its useful outside the context of a standard monthly calendar. It could serve, say, as a header for a table showing weekly specials in a restaurant, or a chore chart of kids, etc.
basic-month-name. This shows the name of the month in a given language (see localization, below).
basic-month-and-year. This shows the name of the month and the year for a given date. The order of the month name and year will match the direction of the text in a right-to-left language like Arabic or Hebrew.
basic-calendar-month. This component puts together the above elements in a typical layout for a month calendar. It stacks together headings for basic-month-and-year and basic-days-of-week on top of a table of days provided by basic-calendar-month-days. Setting the desired language/culture for this component updates all the headings as well as the day shown as the first day of the week.
Note that basic-calendar-month just renders a calendar. It doesn’t handle date selection, although that could be added through creation of another component. The month calendar is inline (directly on the page), but could be incorporated into a dropdown for a typical dropdown date picker. Or you could combine twelve instances of basic-calendar-month together to create a year calendar, etc., etc.
Per the guidelines, these components include an absolutely minimal degree of styling required to get something useful. You would undoubtedly want to style these further to meet your own application’s brand. This should not be too difficult, as web components can be styled through CSS.
To easily and accurately localize these calendar web components, they all make use of the excellent Globalize project sponsored by jQuery. Globalize supports about 350 different languages, locations, and cultures around the world. As it turns out, Globalize already defines everything these components need: which day of the week should come first, the names of the days, and the names of the months. So you can simply tell Globalize to load the settings for a particular language/culture, and then hand that pile of settings to the components, and they’ll set themselves up appropriately. Here’s basic-month-calendar in Japanese, French (in France), and Arabic (in Saudi Arabia):
Note that all text strings here (the month names, and the names for the days of the week) are coming from Globalize, not from the application or the calendar component. Globalize also supports different formats for the names of the days of the week, so you can choose between full and abbreviated headings.
[Aside: an open question for me is whether a calendar for a right-to-left language should have the order of days go from right-to-left as well. I can find some Arabic calendars, for example, that have the first day of the week go in the rightmost column — but I can also find plenty of examples that have the first day of the week in the leftmost column. And all the examples of Hebrew calendars I can find have the first day of the week in the leftmost column. This just goes to show that localization will always surprise you and/or make your head hurt. The Globalize library doesn’t seem to include information on the preferred direction of time, so for now these components assume that left-to-right is generally acceptable.]
To simplify the localization of an app using these components, I’ve put together a simple basic-culture-selector component that can dynamically load all the necessary settings based on the user’s prefered language/culture. (This component can also be used behind-the-scenes as a language/culture settings loader.) Components such as these calendar components can then obtain the right settings from an instance of basic-culture-selector directly through declarative data binding, with no scripting required.
Reality check: Localization is an incredibly complex topic, and language- and culture-aware components are just a part of a solution. To really do justice to a global audience, an app team would need to take a comprehensive approach to localization. Among other things, an app would need some reasonable way to set a default language/culture (based on domain, geolocation, and/or apparent IP location), a way to store language/culture preferences with a user account, and a UI for switching language/culture. It would also help if browser vendors participated in a good standard solution, so users aren’t forced to indicate their preferred language/country/etc. on a site-by-site basis. Still, having solid, localizable components is a good place to start.
Many applications want to render data on a calendar: appointments, availability, and so on. Most calendar widgets are useless in this regard outside a narrowly-envisioned range of scenarios, because they make so many assumptions about what data will be shown. Rather than viewing a week or month calendar as having a particular visual representation, it seems more helpful to consider a calendar as a skeleton or abstract structure capable of holding components for each day whose only requirement is that they can accept a date. How a day component renders that date is entirely up to them.
For this reason, the basic-calendar-month (and -week) components have a dayTag attribute that can be used to provide the name of another component class that will be used to render the individual days of the month/week. The default dayTag value is basic-calendar-day, but this can be changed to any other class. The only requirement on the interface of the indicated class is that it have a property setter called “date” that accepts a JavaScript Date object. This allows one to easily render arbitrary data into the structure of a calendar.
To show this in action, suppose we want to create a month calendar that shows the major phases of the moon (new, first quarter, full, last quarter, or nothing special). To keep things well factored, we start by creating a web component called moon-phase that just renders the phase of the moon as an icon. It doesn’t shown a day number, or anything else, because we just want it to do one thing really well.
We then create a custom day component, either from scratch or, for simplicity, by extending the existing basic-calendar-day component. We drop an instance of moon-phase into that class and add a day number so we get both the number and the moon icon. Finally, we instantiate a basic-month-calendar and tell it to use that class to render the days. Et voilà, with a teeny tiny bit of work, we get a perpetual moon calendar. In U.S. English, this would look like:
[See the live demo]
By building on top of basic-month-calendar, this moon calendar not only avoids the headaches of date math, it also automatically obtains a high degree of localizability provided by the underlying Globalize library. As improvements are made in the underlying basic-month-calendar, the moon calendar picks up those improvements for free.
Here one web component (basic-month-calendar) allows a portion of its UI (the rendering of days) to be overridden by accepting a second web component class as input (via the dayTag attribute). The calendar is effectively an abstract component or meta-component that defines a structure which is completely or partially filled in by another class. This UI pattern parallels the use of abstract classes in programming languages, and seems generally useful in many other component situations.
Patterns like this may go a long way toward ensuring web components can really be general purpose, and may ultimately be a key part of managing some of the date math and localization complexities I’ve touched upon in this post. As some of the calendar issues raised here suggest, it’s notoriously difficult to do anything with dates and time, especially when one wants to localize a UI across a wide range of languages and cultures. The best strategy for ensuring that someone, somewhere has sufficient motivation to fix tricky issues is to maximize the audience for the component. And one way to increase the size of the audience is to make the component as general-purpose as possible. That is, creating a wide range of scenarios for a general-purpose component like basic-month-calendar seems critical to ensure that the component gets sufficient attention to make it reliable in a wide range of circumstances.
[Speaking of open source contributions, I wanted to take this opportunity to publicly thank a few people who offered early contributions to the relatively new Basic Web Components project. @OliverJAsh filed the first bug report on the project, @PascalPrecht submitted the first pull request, and Dave Romero made the first edits to the wiki. Many thanks to the three of them!]
I recently contributed a small handful of web components to the Basic Web Components project, and wanted to share some observations on how designing and building UI with web components is going to be pretty different from how you’ve created UI in the past.
The web components I was working on are related to the standard sort of photo carousel you see everywhere on the web these days:
There are a zillion widgets out there that will create such a thing for you, but they generally are connected to a specific web platform (WordPress, SquareSpace, etc.) or require the use of JavaScript.
A carousel web component, on the other hand, lets you construct such a thing in HTML alone. Here's a carousel component called basic-sequence-navigator:
<basic-sequence-navigator>
<img src=”image1.jpg”>
<img src=”image2.jpg”>
<img src=”image3.jpg”>
...
</basic-sequence-navigator>
You can see a live demo of this component on the Component Kitchen page for basic-sequence-navigator.
With a web component like this, you just drop your images (or other elements) inside of the component, and you get a carousel. No styling or JavaScript required. That’s pretty neat all on its own, but the component’s construction is also interesting in its own right.
Existing carousel widgets suffer from trying to present a final solution. Someone creates a single widget that handles everything: positioning the images, transition effects, Next/Previous buttons, programmatic API, events, and more. If there’s anything about that solution you don’t like, you often have to reject the whole widget, or else spend time fiddling with widget options in hopes of finding a combination of settings that does what you want.
Given that web components lets you build bigger things from smaller things, I wanted to try to factor the carousel as a user experience into simple pieces that you could combine in different ways. Even if you don’t like a specific end result, you may nevertheless find some of the building blocks useful in constructing your own solution.
For starters, consider that the Next/Previous buttons shown above are just a specific answer to the general question: how does a user navigate the sequence of images? Those buttons aren’t the only answer; there are other common answers to this same question. An equally common answer might be putting iOS-style dots along the bottom. So it’s silly to inextricably bundle the general problem of providing navigation through a sequence with the specific solution of Next/Previous buttons.
A better answer is to factor the general behavior into one component, and the specific UI into a separate component. Accordingly, the basic-sequence-navigator component is really based on a more fundamental component called basic-sequence. The basic-sequence component handles transitional effects like sliding or cross-fading, but doesn’t include its own navigation UI.
That means you can wire up buttons of your own (or any UI you want) to drive an instance of the more fundamental basic-sequence component. A crude example of this would be:
<button onclick="document.querySelector('#sequence').previous()">Previous</button>
<button onclick="document.querySelector('#sequence').next()">Next</button>
<basic-sequence id="sequence">
<img src=”image1.jpg”>
<img src=”image2.jpg”>
<img src=”image3.jpg”>
...
</basic-sequence>
You can see a demo of this solution on the page for basic-sequence. It's not beautiful, but the point is that you can build up your own UI from simple pieces. You don’t have to write all the code — you get things like transition effects for free, for example. At the same time, you can create exactly the user experience you want.
Maybe you don’t want any visible UI, you just want to show one image after another on a timed basis. There’s a separate component called basic-slideshow that does just that. It uses basic-sequence under the covers, but adds the notion of a timer and play/stop semantics:
<basic-slideshow effect=”reveal”>
<img src=”image1.jpg”>
<img src=”image2.jpg”>
<img src=”image3.jpg”>
...
</basic-slideshow>
What if you don’t care about transition effects? You can build on top of an even simpler component called basic-modes. That just shows one child element at a time. And even that component is built from simpler pieces, including core-selector, a component that just keeps track of which item in a set is selected (without defining what selecting means or looks like). And that component is built from even simpler one. It’s components, all the way down.
The idea here is that UI shouldn’t be delivered as a huge, final thing with a million knobs on it to cover every conceivable situation. Instead, complex UI should be built up from simpler pieces, each of which do a great job at one thing.
Of course, if you do like the general idea of Next and Previous buttons, but want them to look different, you can use basic-sequence-navigator, and then take advantage of the styleability built into web components. Using CSS rules, you can override the default styling to better match your app’s aesthetics and brand.
The basic-sequence-navigator component has a nice feature most carousels lack: keyboard support! If you press the Left or Right key while the component has focus, the carousel advances, respectively, to the previous or next image. To help make that feature more discoverable, the component sports a focus rectangle when it has the focus.
It’s kind of appalling the web is chock full of photo carousels that can’t be navigated with a keyboard. That not only shuts out a big chunk of people for whom a mouse or trackpad is hard to use, it’s also generally inconvenient for everyone else. If you have to page back and forth through a sequence of images, using Left/Right keys is simply much faster than moving a mouse or finger back and forth to hit buttons on either side of the images.
Some web sites, generally big ones with large staff, can afford to spend time getting accessibility details like keyboard navigation right. But I’m willing to bet that the vast majority of photo carousels on the web today aren’t accessible. The problem isn’t just awareness — the software industry has been talking about accessibility for a long, long time. The deeper problem is that the economics of implementing accessibility are often terrible. If everyone has to implement something like keyboard support on their own, for any single team, the predicted return on the investment is just too low to pursue.
With web components, the economics could improve radically. Once people can share UI solutions as components, even small improvements can potentially benefit thousands of sites. So someone may find it worth their time to add support for keyboard users, or users with low vision, or screen reader users, and so on. Even if the original author of a component (say, me) knows just a tiny bit about the accessibility implications of ARIA support, perhaps there’s someone else out there (you?) who knows ARIA inside and out and can help get it right.
The best part is that, if accessibility can be improved for free, everyone benefits even if most people won’t know they’re making their products more accessible. Most people aren’t going to adopt a component like <basic-sequence-navigator> because it has good accessibility. They’re going to adopt it for selfish reasons — it’s going to save them time.
That’s fine! If someone can just drop in a photo carousel component because it saves time implementing a design, they'll use it, even if they know nothing about accessibility. They don’t even need to know that the carousel's built-in accessibility features exist for the component to help them support a broader audience of end users.
If you’re interested in this approach, and want to learn more about creating general-purpose web components, the Basic Web Components site has a page on 10 Principles for Great General-Purpose Components. If you’d like to take a shot at contributing to the project, the home page provides a long list of components the world could use.
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.
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.
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:
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.
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.
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.
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):
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.)
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:
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.
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.
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.
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.
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.
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.
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...
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.
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.
In many project discussions, it’s been my experience that two calendar-related questions constantly arise:
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:
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.
The last time you had to arrange the furniture in your home — did you create a design first? No. You had a design idea, and then immediately jumped into implementing your idea by moving the sofa and table around until the result felt good.
Hmm… let’s try putting this over here…
Consider these attributes of the typical process for arranging furniture:
You can design software user interfaces this way too.
I had a chance to speak about my own design process at a talk I gave last month at the California College of the Arts in San Francisco, to an engaged audience of interesting students in the school’s MBA in Design Strategy program. There I discussed how my own design process has changed substantially in the last five years to become something I might call designing by making. In this process, the design of a software experience is inseparable from the coding of that experience. In this regard, the process has a lot in common with arranging furniture.
Many contemporary design process artifacts like field interviews, a wall of post-it notes, and paper prototypes reflect an increasingly antiquated premise: that building a real thing is much more expensive than producing a design. Historically, it has been true that designing software with a complex user interface was a minor cost compared to the labor of actually writing the code. In my early days at Microsoft, one might have seen a ratio of one designer to five to eight engineers (developers and testers), because even primitive tasks like obtaining user input or positioning interface controls in a window entailed such extensive, labor-intensive coding. It seemed sensible to invest considerable thought and time in the design phase because it could be many months before the designer would get to experience the actual product for the first time. Unfortunately, that moment of enlightenment often didn’t come until the fully-functional pre-beta builds arrived roughly two-thirds of the way through the product cycle. At that point, when the designer inevitably has new insights into the best design, any big design changes would often needed to be deferred until the next version.
Much software is still designed this way, even though the economics of user interface implementation have changed radically. The effort required to create useful, functional, beautiful, reliable, and performant software application user interfaces has been dropping for years, and this trend will continue for the foreseeable future. About five years ago, the technology reached the point where it became possible for me to create web applications directly. Rather than working in Photoshop, Microsoft Word, or a prototyping tool as before, and handing these designs off to an engineer, I can now directly create the user interface design in code myself.
This is roughly as expensive as the old way of doing things, but with the significant advance that I am now working with a functional artifact — a working user interface — from the very beginning. This turns out to be a transformative difference. Just as you can never predict all the ramifications of a particular furniture layout, you can never fully predict the strengths and weaknesses of a UI design.
Instead, I currently believe it’s best to design something by making it. This means it’s generally not worth a great deal of time to consider the hypothetical implications of a theoretical design. (“Will the user find this clear?”, “Will this meet the user’s needs?”) It’s faster to just build something that actually works, then immediately observe whether it is good or not. Instead of viewing design as a predecessor to making, this is designing by making. The process looks just like the process above:
This process isn’t for everyone. There are software domains that don’t entail a user interface (Mars landers, say), where a traditional, process-heavy design phase obviously holds true. And not all designers can code, nor can all coders design. But I believe that designing by making does allows someone who can do both well to iterate much faster from an idea to a usable interface than a designer who is forced to rely on someone else to write the code.
I believe that in the near future, most software application design will look like this. The trends simplifying the coding of user interfaces will continue and accelerate, as better design/coding tools permit the construction of better design/coding tools. Component-oriented user interface frameworks will allow people to spend less time designing and coding the details of common patterns.
Furthermore, companies with experience in creating tools like Adobe are now waking up to the realities of a post-Flash world, in which the open web is the real application platform to focus on. (Microsoft is also slowly waking up to the prospect of a post-Windows client world, although that change will take much longer, and I’m not sure they’ll be able to change fast enough to stay relevant.) Generally speaking, I have high hopes for innovation in the realm of tools and frameworks, all of which should make it more and more practical for someone like you to do both the design and coding yourself.
Today, it is already possible to have a design process built around coding that is as efficient — or, often, more efficient — than a traditional, artifact-heavy, pre-coding design process. What’s more, the tool chain will ultimately improve to the point where designing a user interface will be as fast as arranging furniture. In the time it takes you to say, “Let’s try moving the bookcase over there”, and actually move the bookcase, you’ll be able to say, “Let’s try a tabbed navigation approach”, and actually switch a design to using tabbed navigation. Imagine what it will be like to design software like that.
Just as geometry builds up complex results from simple axioms, and programming languages build up complex constructs from simple primitives, it should be possible to create complex user interface elements from simple elements. But the lack of great building blocks for web user interface components causes people to waste a colossal amount of time reproducing common behaviors or, worse, forces them to settle for something quick but suboptimal.
Take something as basic as tabs. Every web UI package includes a widget or component that produces a set of tabs, such as the typical example from jQuery UI:
While a tab set may seem to be an irreducible unit of user interface complexity, we can actually decompose its behavior into smaller, simpler chunks:
It should be possible to create UI classes that implement each of these more fundamental behaviors or aspects. It should then be possible to exploit these behaviors on their own, or recombine them with other behaviors to produce other recognizable user interface controls. In effect, we should be able to arrive at fundamental behaviors that behave like the axioms in a mathematical domain or, alternatively, like atoms in a physical system of elements.
The domain of computer science has much to say on the topic of axiomatic design. Programming languages are often predicated on the notion that you can boil down everything you’d want to do in the language to a tiny set of primitive functions. It’s only this small set of primitives which must be written in a lower-level language (e.g., a machine language). Everything else can be built up in the language itself. This not only keeps things clean, it ensures the language’s popularity and survival by facilitating the porting of the language to new platforms — only the primitives must be rewritten, and all the remaining code built on top of the primitives can be used as is. The original example of this axiomatic principle in language design was Lisp, whose story Paul Graham recounts in his article The Roots of Lisp. (The full article is available on his site in the original Postscript version, or in various converted PDF versions.) From his article:
In 1960, John McCarthy… showed how, given a handful of simple operators and a notation for functions, you can build a whole programming language.
[McCarthy’s] ideas are still the semantic core of Lisp today. It’s not something that McCarthy designed so much as something he discovered. It’s not intrinsically a language for AI [artificial intelligence] or for rapid prototyping, or for any other task at that level. It’s what you get (or one thing you get) when you try to axiomatize computation. … By understanding [Lisp] you’re understand what will probably the main model of computation well into the future.
Can we determine a similar axiomatic deconstruction of user interface elements? That’s a topic I’m acutely interested in, and I believe the answer is yes. Even through graphical user interfaces span a range of devices, platforms, and frameworks, the underlying collection of distinct user interface behaviors is quite consistent: clicking one thing something makes something else appear; items in lists are given consistent representations and behavior; modes (for both better and worse) constrain the user’s attention and powers; and so on. It should be possible to boil those consistent behaviors into reusable code.
The result of this decomposition is a set of UI primitives which is significantly bigger than the canonical tiny set of user interface controls: a push button, a radio button, a check box, a text box. Of all the aspects numbered above, only #6 (push buttons) are available as a native browser control. Web developers are generally forced to recreate all the other aspects through combinations of CSS and JavaScript. That's inefficient and error-prone. As noted above, even something as seemingly straightforward as stacking two regions on top of one another can prove unexpectedly complex.
The actual set of web UI primitives is probably an order of magnitude larger than what browsers expose as interactive UI controls. At the same time, the set of really general purpose contemporary UI (see this article for a breakdown of UI elements by context-specificity) is not so large it can't be enumerated or understood. For today’s typical mobile or web application, I believe a reasonably comprehensive collection of UI primitives would number in the 100 – 200 range.
What would those primitives be? My work on the QuickUI Catalog is an attempt this question. It’s a work in progress, and is by no means complete. It currently includes controls which shouldn’t be there (they’re really just sample uses of an underlying component), and on the other hand doesn’t (yet) include enough controls for common situations like mobile. Nor is the set of controls completely stable yet. I occasionally realize two controls exhibit similar behavior whose implementation should (or shouldn’t) be shared, which results in both minor and major refactorings. Nevertheless, the Catalog already represents a highly useful starting point for creating application UIs.
Let’s return to the tab set example above. The QuickUI Catalog includes a Tabs control for this purpose, which can be used as is. But that Tabs control is simply a combination of lower-level components corresponding to the attributes listed above:
All these derive from a common Control base class.
We can show the relationships between all these classes in a graph, where a solid line represents an “is a” relationship (one class derives from another) and a dotted line shows a “has a” relationship (one class makes use of instances of another class):
This arrangement entails a lot more pieces than a typical web user interface platform. The browser itself only provides a native button. Most existing web user interface frameworks provide some button class wrapper (such as BasicButton here) and a tab set class (Tabs). They may or may not expose a general purpose UI component base class (here, Control). The tab set class is typically fixed in a monolithic implementation, and can only be modified via parameters the framework designers have anticipated beforehand.
Traditional client-side UI frameworks (e.g., Windows Presentation Foundation) do have rich class hierarchies, although even their UI primitives tend to be too course-grained. And contemporary web UI frameworks rarely have good building blocks. (Some people claim the Sencha framework does, but it's unfortunately encumbered with developer licensing fees, and requires you to build your app on top of a proprietary substrate. To me, that's moving in the exact opposite direction of web development trends.)
The main obstacles to UI like this on the web may have multiple causes, including the fact that the web's primary client-side programming language JavaScript, still has no native support for traditional object-oriented classes. Moreover, the browser doesn't yet expose a model for modular component composition, which creates a lot of work for a UI framework's creators.
In the above implementation of a tab set, all the lower-level pieces are directly available to the user interface designer and developer. These can be used on their own, or combined with other types of elements to create other user interface elements. And, significantly, new elements constructed with this approach are, by default, extensible and recombinable in their own right. In a subsequent post, I plan to show some of the other sorts of UI controls which can be created by combining some of the pieces above in different ways.
As noted above, this Catalog implementation isn’t perfect. Among other things, there are inherent limitations on what you can achieve with a classic single inheritance hierarchy. But, overall, this feels like a promising direction, and in practice is a highly efficient way to create web apps. Above all, this axiomatic approach feels like the right paradigm for building UI.
McCarthy's big advance with Lisp wasn't to create programming language primitives — all programming langauges have primitives. His insight was that the primitives in programming languages of the time weren't primitive enough. Instead, you should break a language into irreducible axioms, and let people combine those axioms to create any new language functions they need. The functions you create with those Lisp primitives are just as powerful as any pre-packaged functions created with those same primitives by the language's designers. That is, there's nothing special the language designer can do you which you cannot also do.
Similarly, a UI platform should give you a powerful set of axiomatic appearances and behaviors and a means to combine them to create new elements which are every bit as powerful as those elements that come bundled with the platform. This is why attempts to build a tiny handful of new controls into web browsers is almost completely uninteresting to me. A new date picker in the browser, to take just one example, is just never going to solve your date picker needs. It's like the FORTRAN committee adding yet another hard-baked statement to the language. What's infinitely more interesting is a UI platform that gives you the building blocks you need to build a date picker of your own that's as powerful as anything in the browser itself.
Web app designers and developers spend a staggering amount of time recreating common effects and behavior that have already been done many times before on other sites, or within their own organization, or in their own code on previous projects, or — worse yet — in their own code on the same project. You may spend days and days carefully reproducing common UI behavior that can readily be found in other apps: menus, dialogs, in-place editing, progress feedback, and on and on. The web wasn’t built to solve those problems, so you have to solve them — over and over again.
This situation is already at least partially avoidable with current web frameworks that permit the creation of reusable UI components. As a case in point, I recently created a sample Contacts application in the QuickUI framework. The app sports a reasonably interesting user interface, but the bulk of its behavior is driven by shared components from the QuickUI Catalog that provide layout, visual effects, editing behavior, list management, and keyboard navigation.
Having built a handful of web apps in QuickUI now, there’s a pretty clear pattern to the balance of UI components used in these apps: about half of the UI code is comprised of components directly from the Catalog or from previous projects. And, in every case, the project itself has generated new, sharable UI components.
Look at your app’s UI elements — at every scale, from page, to region, to widget, to tiny little visual element — and ask yourself: has anyone done this before? Will someone do it again? If this were a component, could I be sharing it with someone down the hall, or at another company? In asking these questions, you’ll generally need to scrape away purely stylistic attributes such as color and typography, and focus more closely on behavior.
As you consider these question of UI reusability, it becomes apparent that the audience for a reusable UI element varies in size, depending on the degree to which the UI is solving a problem that comes up in other contexts. Some UI is completely specific to the context of a single feature, while some UI patterns are extremely general and come up everywhere.
It’s possible to categorize your UI elements according to this aspect of context-specificity. Having created a half dozen or so web apps of reasonable complexity in the component-orient QuickUI framework, the proportional breakdown across these categories has been very consistent. This leads me to hypothesize that the general proportions of these categories are roughly consistent across most web apps.
Such a breakdown might look like this, ordered from most context-specific to most general:
The percentages I’ve given above are rough, but drawn from examining the UI code in apps I’ve written over the last few years. Those apps were already carefully componentized, and focused on code reuse, so I expect a more thorough analysis of more web apps would confirm that the numbers above are conservative. That is, the actual degree of unnecessary reimplementation in a typical web application is probably far higher. Without a component foundation, the most expedient way to replicate a given behavior is often to cut-and-paste it from somewhere else in the app’s source, then hack on the result to fit the new context. The app may not only be reinventing the UI wheel, but doing so multiple times in the same codebase.
If the above breakdown is even roughly correct, then consider a new web company entering an existing market who writes their app UI entirely from scratch. Even if it were extremely well-factored, 50% of all the UI code they write would be reinventing the wheel, solving domain-specific or general purpose UI problems which have already been solved before. While that sounds extreme, it’s probably not that far off the mark for most companies. While most apps consume at least some third-party UI elements (to implement a Facebook “Like” button, say), in many cases the typical company is just nibbling at the edges of the problem. And, if we assume that office politics and other factors prevent them from sharing code internally, the percentage of unnecessary re-invention may be much higher.
No matter how you slice it, chances are that most app teams are writing way too much UI code. Because the web lacks a real component model, most companies write reams and reams of non-modular, non-reusable UI code. If they were to build their apps on a UI framework that let them use and extend components, they could probably avoid writing much of the UI code they write today. To put this in business terms: if they were to componentize their UI effectively, they could get the same amount done in half the time or with half the resources. Obviously adopting a component strategy and reusing components have costs of their own, but I expect those are dwarfed by the mind-numbing scale of solving the same problems again and again.
There already are component frameworks for developing web app user interfaces. I’m obviously heavily invested in QuickUI, but you can find others out there as well. Given the huge savings they can make possible, they’re worth a look.