Recently, the Codrops newsletter washed an article into my mailbox called “HTML: The Bad Parts” dealing with accessibility problems with standard HTML elements. To my surprise, I found the date input among the list of problematic elements although its accessibility is not bad at all in 2024.
Is it that awful to use?
Full disclosure: I am a diehard keyboard user when it comes to online forms. This is because I am old and by that I mean DOS Shell-old or Norton Commander-old. I will literally tab my way through anything that looks like lists or inputs like the touchpad never existed.
I have never noticed any problem with the native date input: I can recognise it easily and I can enter a date without having to tab or click somewhere else. I can step all numbers up and down with the arrow keys and I do not need to tab to move from day to month to year. The date field can have a minimum and maximum value, so I do not accidentally enter my birthday as a 19th century event (even though I feel like it was sometimes).
One complaint is locale: If you set your browser to plain “English” for example, it will assume you use the American date format m/d/Y. This is confusing because the largest part of the English-speaking world does not use this date format. Browser developers should include a setting for ones preferred format. However, if you get it wrong, you get it wrong immediately since the date input will not let you enter “30” as a month. You do not need to worry about slashes or dots or how many digits the year needs either.
The alternatives
Mainly two replacements to the native date input are suggested by its opponents. In contrast to native date inputs, I run into trouble with these all the time.
Three-part input field
They look like one field but really are three inputs. You often need to tab through these fields manually but you cannot see that because they are styled in a way to make them look like a single field. To achieve this appearance, these fields sometimes lack labels entirely, which renders them inaccessible.
To make the three-part field behave like a single date input, more often than not some javascript is used to autofocus the keyboard user on the next date part once they have input a valid number. This way they do not have to tab from day to month to year. However, if you made a mistake or just want to change the date, you cannot go back to month or day with the left arrow key as a real date input would allow. You need to back tab. But the month and day fields have already been filled in with a valid number. So once you get there, the JS immediately autofocusses you on the next field. The month and day fields become unreachable by keyboard navigation, if you need to go back and correct.
Last but not least, these three input parts are often number inputs to limit the range of available dates and avoid input mistakes. Numeric inputs have worse usability and validation problems than date inputs. If you must use a three-part solution, please use <input type="numeric" inputmode="numerical">
One field to rule them all
There is also the one-field input, in which you have to enter the date like normal text — and that is including separators. Whether you have to use slashes or dots, whether you need to enter a two- or four-digit year, and what order to use for the date parts, you only find out after the field fails to validate. Also, on mobile, the full keyboard instead of the number pad comes up, which is incredibly tedious to use when all you want to do is enter digits.
Apropos validation: The native date input validates automatically. But how do you validate a date in a text field? What I usually see is simply checking for not allowed characters and correct length. But this does not prevent users from making mistakes by accidentally entering an invalid date like February 31 or an implausible one from the last century. You have to write more complex validation rules in JS to make this work. What mostly happens instead (especially in the WordPress world) is mindlessly running Jquery Validate1 on your form and that does nothing to help.
What about the date picker?
I whole-heartedly agree: The native desktop browser pickers for the date inputs are all horrible. They are small, hard to read or hard to navigate, or slightly bonkers (Safari’s weird rolodex thing), and sometimes do not even open when you click the date (but only when you click the tiny icon, go figure). The mobile UIs for picking dates on the other hand are good and mostly well thought out.
It comes as no surprise that the author of “HTML: The Bad Parts” mostly complains about the pickers:
Malynk, HTML: The Bad Parts (2023)
- On Chrome desktop, the calendar button cannot be tabbed to.
- On Safari desktop, the date picker cannot be closed using keyboard.
- On Safari desktop, the date picker is minuscule and cannot be scaled up.
- On Chrome and Firefox Android, the date input cannot be typed into, forcing the use of the clunky calendar UI even if the date is familiar to the user.
Here is the thing: As a keyboard user, I do not care about the date picker to begin with. Filling in a date input with the arrow keys or by typing numbers is fast. Navigating a calendar month sheet like a game of pacman is not. Items two and three on that list are not really that relevant to keyboard users.
For screen reader users, date pickers per se are a barrier to access. They have to find their way through complicated navigation options for month and year. When they navigate the days of a month, the screen reader attempts to read out all their labels, which is a lot of noise. Focus in and out events do not work properly in most browsers. You cannot leave the picker without actually setting a date and this is not obvious at all. I will venture out to say that any screen reader user would prefer to simply enter a date instead of dealing with a picker.
Therefore, in my opinion “On Chrome desktop, the calendar button cannot be tabbed to” is not a bug. It is a feature. As a keyboard user, I do not want to tab to the picker after I have already entered the date. I want to tab to the next input or form field. As a screen reader user I do not want to go there at all for the reasons described above. Not being able to activate the picker is not a barrier to access. The picker itself is.
As for the mobile UIs, dismissing them as “clunky” seems a bit odd. It is true that many users experience difficulties selecting their birth year with the native UIs — and that is with Safari in particular, not Android. However, “date of birth” is far from the only use case for date inputs. Date inputs are also widely used for filtering, for example on booking or event calendar sites. Choosing month and date on mobile is convenient enough. By comparison, having to touch-activate three different numeric fields side by side certainly is a sub-optimal input method. Typing a date into a text field on mobile is not comfortable either, especially for older users. For screen reader users though it would be practical to ‘type’ into the date input on mobile by using speech recognition. Lack of this option is the only valid point made above.
What to do
I would like to be able to disable native date pickers across all browsers, either to disable them entirely or to launch a custom picker when hitting enter on the date input. Currently, Chrome is the only browser to let you disable or replace it with a custom solution. Firefox does not expose the shadow dom for the field and e.preventDefault() does not work with keyboard events properly (meaning you cannot filter them by key used). This is sad, Firefox! Safari is the mostly same. With both browsers, you can only visually hide the calendar icon by putting something on top of it, which would at least prevent clicks.
With the current state of things, I would recommend:
Never force anyone to use a date picker, neither a custom nor native one. Always allow for inputting the date with the keyboard.
If year is relevant to your field and you truly believe the mobile date input UI is too hard to understand for your users, go for the three-part text inputs with inputmode=numeric. Do not try to make them look like a single field. Clearly display three fields with labels for month, day, and year. Do not deactivate tabbing and do not autofocus on input. Just let the fields work like the normally do. Make sure you validate them properly.
If year is not important to you, there is no reason to avoid the humble native date input. It is easy to use for everyone and easy to develop with with its custom properties and validation. Even if you want to implement a custom picker, the presence of the native one is not necessarily a hindrance.
You can prevent clicks on the icon by visually hiding it or deactivating it in Chrome. You cannot prevent keyboard users accessing and hitting enter on it in Firefox and Safari. When users tab to the icon, if they can see, they will probably just tab on, since seemingly nothing is focussed. Screen reader users might accidentally activate the native picker but since they cannot see that there is also a custom picker, it does not really matter.
And here is a controversial opinion: Personally, I would always disable access to custom pickers by keyboard since they are so hard and annoying to navigate and in particular without sight. If you feel some visual representation for the selected date is necessary, for example when selecting a date range, you could show your custom picker and let it reflect the current range selected on keyboard input events. For visually impaired users you can always announce the currently selected range.
The bottom line here is: Could <input type=”date”> be improved? Certainly. Is it a barrier to access? Not at all. But lack of a standard interface to enable/disable the pickers is certainly an annoying hindrance to designing a consistent UI (at least on desktop).