Search topics
Date pickers that can't be typed in or used by keyboard
A delivery date field is read-only and opens a calendar of plain divs on a click, so a keyboard can't enter a date and a screen reader hears only bare numbers, and once the field takes typing, nothing says whether the day or the month comes first.
<input id="delivery" type="text" readonly> The problem
Keyboard users can't enter a delivery date at all, screen reader users hear bare numbers with no chosen day and no today, and once typing works, nothing says whether 11/12/2026 means 11 December or 12 November.
A shop's checkout asks for a delivery date. The field shows "Choose a date", and a click opens a calendar under it for November 2026, with today, Monday the 2nd, in bold. A click on Thursday the 12th fills the field with 12/11/2026. With a keyboard, Tab reaches the field and stops there: typing puts nothing in it, Enter and the arrow keys open nothing, and the next Tab moves on to the next control. There is no way to give a date, so the order can't be placed. A screen reader announces "Delivery date" as a read-only text field, which tells its user the field can't be typed in and offers nothing else. If the calendar is opened with the mouse, a screen reader reads each day as just its number, "12", with nothing to say it can be chosen, which day is chosen or which one is today.
The shop's quick repair is to let the field take typing. Now someone who writes dates month first types 11/12/2026 for 12 November, and the shop, which reads every date day first, books the delivery for Friday 11 December, a month late, without a word. Someone else types 12 Nov 2026, which the shop can't read as a date at all. The label says "Delivery date" and nothing more, so there was no way to know which form it wanted. The calendar is unchanged, and still fails as before.
Success Criterion 2.1.1 asks that everything a mouse can do can be done with a keyboard. The field has readonly, so the browser lets it take focus but refuses typing, and the only way to fill it is the calendar. The calendar opens on a click event, which a text field doesn't fire for any key, and its days are div elements, picked by a click handler on the box that holds them, and a div can't take focus. The browser allows all three, and none is invalid on its own; together they leave the date to the mouse.
Success Criterion 4.1.2 asks that a control's name, role and states are available to assistive technology. On screen, the days are controls. In the code, they are divs: no role, a name that is only the day number, and the chosen day and today marked by selected and today classes that change only how they look. A browser passes roles and states on from the markup, and a class carries neither, so a screen reader has nothing to say about them.
Success Criterion 3.3.2 asks for labels or instructions where content needs input, and its Understanding page gives, as an example, a date field with text that states the format. A date can be written day first, month first or year first, with slashes, dashes or words, and the second Before reads only one of these without saying which. "Delivery date" names the field but doesn't say how to fill it in, so 11/12/2026 is taken for a different day from the one meant, and nothing on the page shows that it happened.
A delivery or booking date is often required before payment, so a field that can't be filled without a mouse stops the order. On a phone, a tap still opens the calendar, so touch testing rarely shows anything wrong, which is part of why this field survives so long.
4 of 10 groups affected
- No vision (affected)
- Low vision (affected)
- Colour vision (not affected)
- No hearing (not affected)
- Hard of hearing (not affected)
- No speech (not affected)
- Motor (affected)
- Reach, strength (not affected)
- Cognitive (affected)
- Seizures (not affected)
- Limited manipulation Keyboard and switch users can't type into the read-only field or reach any day in the calendar, so they can't give a delivery date and can't place the order.
- Without vision Screen reader users meet a field announced as read-only with no way in, and a calendar of bare numbers, with nothing to say they can be chosen, which one is chosen or which is today.
- Limited language, cognitive and learning abilities When the field doesn't say which order it wants, people who write dates another way get a date a month off with no warning, or a date the shop can't read, and have to guess again.
- Limited vision People with low vision who have trouble finding or following the pointer on screen can't type the date or step through the days from the keyboard instead, and have to find the right small number with the mouse.
A scanner such as axe finds a text field with a label and passes it: readonly is valid, and no rule says a date must be typeable. The calendar isn't shown until a click, and its days are divs with no role or ARIA, so there is nothing for a rule to fault. Whether "Delivery date" says enough about the format is not a question a rule asks. Date picker libraries can produce the first Before's read-only field by default: flatpickr, for one, makes its field read-only unless its allowInput option is set. AI assistants asked for "a date picker" can write the calendar from divs, or add role="grid" to it and leave the days with no focus and no aria-selected. Only typing, opening the calendar from the keyboard and listening shows whether it works.
Try it
Set the delivery date to Thursday 12 November with the keyboard alone: Tab to the field, then type the date or open the calendar.
- Broken 1: Tab to Delivery date and type, or press Enter or the down arrow. Nothing goes in and nothing opens; only a click opens the calendar.
- Click the field to open the calendar, and point at a day: the panel shows what a screen reader reading under the mouse says, just the number, never which day is chosen or which is today.
- Broken 2: type 11/12/2026, the way 12 November is written in the US, and press Tab. See which day the shop reads.
- Apply the fixes. Type the date, or in the dialog fix, Tab to the calendar button, press Enter, and move with the arrow keys, Page Up and Page Down.
Broken Can you fix this?
Screen reader says:
(Tab to Delivery date)
The fix
Let the date be typed, in a format the page states or in a native date field, and make any calendar a dialog whose days the keyboard reaches and a screen reader reads.
- 1The date can be typed, and the field says how to write it, or is a native date field.
- 2Any calendar opens from a button and works with the arrow keys, Enter and Escape.
- 3Each day is read with its full date, and the chosen day and today are exposed in code, not only drawn.
A read-only field and a calendar only a click opens
<label for="delivery">Delivery date</label><input id="delivery" name="delivery" type="text" readonly placeholder="Choose a date"><div class="calendar" hidden> <div class="cal-head"> <span class="prev">‹</span> <span class="cal-month">November 2026</span> <span class="next">›</span> </div> <div class="cal-week"> <span>Su</span> <span>Mo</span> <span>Tu</span> <span>We</span> <span>Th</span> <span>Fr</span> <span>Sa</span> </div> <div class="cal-days"></div></div>A native date input
<label for="delivery">Delivery date</label><input id="delivery" name="delivery" type="date">Why this fix: Use native HTML first
The field refuses typing, the calendar opens only on a click, and its days are divs no key can reach, so a keyboard can't set a date at all. The days have no role, and the chosen day and today are classes, so a screen reader reads only numbers.
The browser lets people type each part of the date in turn, gives them its own calendar to pick from, and tells a screen reader the field's name and role and the date in it. It also takes the order of the parts from its own language settings and, in most desktop browsers, shows it in the empty field, such as dd/mm/yyyy, so the format is stated without any words of yours, and the value sent is always 2026-11-12, whatever the order on screen. On a phone, a tap opens the system's own date picker. The script and the styles are gone: there is no calendar left to maintain.
This passes as far as each browser's own control does. Its calendar can't be styled. It can limit the range with min and max, but it can't shut out single days, such as Sundays or a sold-out day, so those have to be refused after the date is chosen. Browser and screen reader pairs read its parts differently, so test the ones you support. The order follows the browser, not the page, so a Japanese page in a browser set to US English shows month first; don't write a format of your own beside a native date field, since it may not match.
Both pass 2.1.1, 4.1.2 and 3.3.2. The native date input needs no script: every browser gives its own keys, its own calendar and its own announcements, and phones get the system picker. Choose it when any day in a range will do, and the browser's look for the calendar is acceptable. Build the typed field and the dialog when some days must be shut out, such as Sundays or days with no slots, or when the calendar has to show more than dates, such as prices, and accept that its keys, states and touch behaviour are yours to test and maintain. Either way, the date can be typed.
A typed field with its format and no calendar at all is a fix on its own; a calendar is only worth adding when it works as the dialog above does, since the second Before shows that an old one left beside the field still fails. Keep the field working if the calendar script fails to load. If a library draws your date picker, switch on its typing option, such as flatpickr's allowInput, and check its calendar with the keyboard and a screen reader as in the steps below before trusting its documentation.
State the format in visible text, not only in a placeholder, which disappears as soon as someone types; see form fields with missing or mismatched labels. Read forgivingly too: a date with or without a leading zero, or with dashes or dots instead of slashes, can still be read in the stated order. Showing the date back in words beside the field, such as "Thursday, 12 November 2026", lets people catch a misread day before the order is sent.
Days that can't be chosen, such as Sundays, still belong in the grid, so the weeks line up: mark them with aria-disabled="true", let the arrow keys pass over them, and say why in text near the field. A native date input can't shut out single days: min and max set only the first and last day.
Other dates and times need other fields.
- A date people already know, such as a date of birth, is quicker to type than to find in a calendar that opens on today's month. Use separate day, month and year fields in a fieldset with a hint, as the GOV.UK date input does, or a single typed field with its format.
- A time can use a native
<input type="time">, or a typed field that states its format, such as "24-hour, for example 14:30". A few fixed delivery slots are radio buttons. - A scrolling wheel of hours and minutes built from divs fails as the first Before does: give it the keys and roles of a native control, or use one.
A calendar that opens and takes focus as soon as the field receives focus is a different failure, covered in dropdowns and fields that change the page on their own.
Fixing this with an AI coding assistant? Get this guide as Markdown, or get every guide in your coding agent.
Verify the fix
5 checks, no mouse.
Test with: Keyboard, Screen reader, Zoom, Forced colors
Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the shared date field or calendar component changes.
Limits
This is a starting pattern for a single date. It doesn't cover choosing a range, such as check-in and check-out dates, time zones, or calendars other than the Gregorian one, such as Japanese era years. The snippets leave out checking the date against the days the shop delivers. Test the complete journey, with your real dates, in the browsers and assistive technology you support, on a phone as well as a desktop.
This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.
References
- WCAG Understanding: keyboard (opens in a new tab)
- WCAG Understanding: name-role-value (opens in a new tab)
- WCAG Understanding: labels-or-instructions (opens in a new tab)
- WCAG Technique G89 (opens in a new tab)
- ARIA APG: datepicker-dialog (opens in a new tab)
- w3.org: wai-aria-1.2 (opens in a new tab)
- developer.mozilla.org: date (opens in a new tab)
- design-system.service.gov.uk: date-input (opens in a new tab)
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.