Dec 15: The anatomy of a good date and time widget


This is the fifteenth post in the FastMail 2015 Advent Calendar. Stay tuned for another post tomorrow.

Following on from our post a few weeks ago on the design of a good credit card form, today we're going to analyse the design of two other common widgets: date and time inputs. Getting these right was vitally important when we were designing our calendar, as they are in frequent use when creating and editing events.

As date and time input is such a common use case, you might expect browsers to already have great support built in. And with HTML5, there is some built-in support in recent browsers, however this is a non-starter for us as we still support back to Internet Explorer 8(!) in our interface. If the native version were amazing this might still be worth using when we can, but most of the current implementations are ugly and not super usable, plus providing support is a nightmare when it behaves differently in every alternative browser!

So, of course, we built our own. Here they are:

If you're reading this in an email or RSS reader, you'll probably need to go to the original blog post to try the demo.

Let's talk about the date input widget first.

The currently selected date is displayed in a localised compact date format. (The above is in the most common format, dd/mm/yyyy. American users of FastMail get mm/dd/yyyy, and there are other localised formats as appropriate). The textual display is inside a standard-looking text input, making the editing affordance obvious.

Unlike a standard text input form though, we know the user is entering structured data – a date – so we can make a number of improvements to aid in swift entry. For a start, the user does not have to enter it in exactly the same format the date is displayed. The control accepts most reasonable formats, for example "25/12", "2015-12-25", "dec 25", "25 december", or "last fri in dec" (all of which result in the same date). It even accepts things like "last wed" (which is Wednesday, 9 Dec 2015 as of this blog post publication) or "first mon in feb 2017" (Monday, 6 Feb 2017). We have open sourced the code that does the date parsing as part of our Overture JavaScript library.

You can also interact with the control using the arrow keys on your keyboard. The up/down arrows will advance through the next/previous value for the part of the date where the cursor is currently situated (day, month or year). Holding down shift in combination with the arrow keys allows you to advance more rapidly.

These two features can actually be combined. For example, you can type "12 feb 2014", then realise you want March, and use the up arrow with the cursor focussed on "feb" to change to "12 Mar 2014".

Of course, sometimes it's easier to see a graphical representation of the dates in a standard calendar format and use the mouse. The integrated calendar button pops up a standard mini calendar which can be used to select a date. We've made sure the click targets are all well-sized and use a swift animation when moving between months to show the connection between the two sets of dates. Everything is localised of course, including the order of the days of the week (again the US like to be different and start the week on a Sunday, while most of the world thinks it starts on Monday, and a few random outliers pick yet another day).

Moving on to the time input widget, we find many of the same features. The time is again displayed in a standard text input field in localised format, including the use of am/pm or 24h time as appropriate (this is also configurable independently of the language within our interface). In the demo on this page, we have set it to use 12h time.

Again, it will accept a variety of input formats, regardless of how it displays the time, for example "1930" or "7p" or "10:02 am" or "11". The up/down arrow keys will also increment/decrement the unit under the cursor. Since event times are rarely needed to the nearest minute, we shift the minutes in 5 minute increments by default, but you can hold down alt to move by 1 minute intervals. As with the date, you can also hold down shift for bigger intervals.

The graphical time picker is perhaps more interesting than the date picker, influenced by the research and design work of Jan Miksovsky. Rather than just use a list of times that is difficult to scroll through, we present the times in a 2D configuration, with the (more common) daytime hours on the left, and the night times on the right, the background of which is grey rather than white to subtly suggest darkness. The least common times (the wee hours of the morning) are in the least prominent position in the bottom right. There's no scrolling, so each time is always in a spatially consistent position. The hours are vertically aligned and correctly use AM/PM or 24h time as per the current localisation setting. Further columns allow quickly setting time to the nearest 15 min increment, although to reduce clutter these are only shown on hover and when selected.

Our testing has shown this is much faster then a simple dropdown list of times, and intuitive to use.

There's an old saying: "take care of the pennies and the pounds (or dollars) will look after themselves". We think the same is true to an extent with our design work. The attention to detail on even the small widgets adds up to a much more pleasant overall experience.