Maybe You Don’t Need a Date Picker

July 5, 2019 ; 14 Comments

Calendar controls, date pickers, date widgets, whatever you call them, however they are described, they follow the same basic principle — present the user with a calendar to enter a date (and sometimes a time).

The native implementations come from browsers when authors use <input type="date"> . Usually a calendar grid, but sometimes built to look like a broken slot-machine or configurable date rubber stamp that your accountant uses.

Frameworks and libraries offer their own take on date pickers, with many more options from third-party developers. These appeal to developers who want control over the visual style, and sometimes function, of the date picker. Particularly developers who want to avoid a different experience across browsers.

The problem is that nearly every implementation of a date picker is a barrier for some set of users. I can comfortably say every one that I have seen is a problem, though perhaps there is a wonderfully robust one somewhere. Even the ARIA Authoring Practices, which is more comfortable with imperfect patterns, has not deigned to create a date picker.

Challenges

I have been testing with users for about 20 years (so far). Something I see over and over again is the frustration with date fields that are anything other than a plain text field for well known dates (like birthdays). They can anger users. Enough that I have seen users quit a test (more than once).

Users do not want to have to stop their flow and learn this new user interface. They don’t want to experiment to see what keys work, or read a pile of instructions. They want to enter a date and move on. This applies just as much to native date pickers. They may only use their phone or computer to email and surf the web, not enter extensive date-specific information on a regular basis.

A developer may use a date picker a few times a day. Every few minutes when building a screen with a date picker. Heck, maybe only once or twice a week. But a developer may have used date pickers in one month far more times than an average user in a year or a lifetime.

Accessibility

I have not touched on the accessibility issues with date pickers. The ones that claim to be accessible aren’t.

For example, we know <input type="date"> is a problem for voice users across browsers. Graham Armfield already produced a thorough report on the accessibility of the native control and came to conclusion that nope, it is not accessible.

I am constantly tossed date pickers from libraries and asked to evaluate them, and they are typically an accessibility quagmire. There is a reason most accessibility professionals tense up at the mention of date pickers.

Validation

Using third-party or native calendar controls can make a developer feel that the validation is handled. Handled by the collective intelligence of everyone who worked on the control.

But the developer still has to provide validation outside of the control. Sometimes validation is needed to support the fallback state for older browsers. Sometimes it is there to honor progressive enhancement. But mostly there should be server-side validation because we know scripts break and resources don’t load and data can be bypass client-side validation.

I cannot imagine that developers are going to let user-submitted content directly into their data structures without scrubbing it in some minimal way. And not just because of the fear of Little Bobby Tables paying their site a visit. As a skilled user, I can get around confounding controls by injecting the values I want using the browser’s dev tools, and developers typically account for data coming through outside of the carefully crafted client-side validation.

The point is, robust web sites and applications already do validation on the data outside of that provided by the control.

An Alternative to Date Pickers

Users generally do not want a complex date picker every time you ask for any date. At least not users with a keyboard.

Text Field

Previously I have relied on plain text inputs as date fields with custom validation for the site, typically using the same logic on the client and the server. For known dates — birthdays, holidays, anniversaries, etc — it has tested well.

Text Field with Messaging

In this prototype I am still using a text input for the first field, but I also use client-side script to convert the data to a human-readable date that I present to the user. This way a user can get immediate feedback and worry a bit less about matching a specific arcane data format the developers prefer.

In short, I am trying to deliver far less code (and confusion) to the end user while accepting a broader range of date formats. I am letting the robustness principle drive my approach.

Prototype

See the Pen XQBgNO by Adrian Roselli (@aardrian) on CodePen.

You will note that I ask for a U.S. date format. The weirdest one. This can be adjusted, of course, but I chose it to demonstrate how a globally confusing format benefits from immediate feedback.

The script to convert the date is the minimal amount of code to demonstrate the effect. It is not production-ready. It is not even good. Try it by entering “7 5 19”. Ideally, the date your script generates is the one you submit with the form.

Note the ARIA attributes, the connections between the fields, and use of <output> to hold the message. These are all there to make sure it is useful for screen reader users and voice users.

<label for="BDay01" id="BDay01Label">Birth date <span>(MM/DD/YYYY)</span>:</label> <input type="text" id="BDay01" aria-labelledby="BDay01Label BDay01error" aria-describedby="BDay01confirm" onblur="valiDate(this.id,'BDay01confirm','BDay01error');"> <output class="confirm" id="BDay01confirm" aria-live="assertive" for="BDay01" form="Form"></output> <div class="error" id="BDay01error"></div>

For more on <output> , read Scott O’Hara’s post <output> : HTML’s native live region element .

Testing Feedback

Dragon Dictate users are generally frustrated with all calendar controls, including the native ones we get from type="date" . In an informal test, this one proved usable.

Informal tests (anecdata) from other users showed this approach was no worse than a text field and far easier than a calendar control.

Places This Will Not Work

There are plenty of situations where a plain text field (with or without the messaging feature I prototyped) will not work.

If you need to see chosen dates, unavailable dates, weekends, holidays, date spans, date ranges, dates where counts from start or end dates matter, and so on.

Wrap-up

What we know is that native and custom calendar controls are often a problem for users and applied where they are not needed. Before dropping the code on a screen as a matter of habit, consider if it genuinely helps the user or just your workflow.

I do not propose a perfect solution for the narrow use case I identified, but I am hoping it spurs rethinking the casual application of a more complex pattern than is often warranted.

Tommy Feldt has put together a proof of concept that works similarly to my example (mine outputs as text, this one to a calendar view). You can find his Inclusive Dates datepicker on GitHub and play around with the demo.

If you play around with it you will see it handles odd dates similarly to mine (try 02/31/1995 from the comments below). I suggest you test it for localization support (honoring dates in your locale).

The calendar uses a native <table> but neuters the semantics with role="presentation" (as opposed to using a grid role, if any change was needed). So I would consider adjusting that.

In the post Natively Format JavaScript Dates and Time , Elijah Manor talks about native JavaScript functions such as toLocaleDateString() , toLocaleTimeString() , and toLocaleString() (which I use in my demo).

Sadly, it leans on screen shots without alt text and a video sans captions, but the content may be helpful to understand different ways you can use these functions that might fit your use case. Particularly if JavaScript is normally not your thing.