TLDR (summarized by Grok)
New opt-in settingUSE_HTML5_DATE_INPUT(defaultFalse) that makesDateInput,TimeInput, andDateTimeInputrender native<input type="date/time/datetime-local">instead of<input type="text">. Browser support is now ~97% globally (including Safari since 2021). It's fully backwards-compatible: off by default, overridable per-widget, and the admin's JS calendar gracefully defers to native pickers. Accessibility is at least on par with the existing JS widgets (which just got improved via #36459 and #36458). Main win is touch/mobile UX with platform-native pickers.
Proposal branch here, diff with main branch here.
Following the suggestion from Jacob on ticket #37083, I'm opening a dedicated forum thread to revisit the idea of adding native HTML5 date/time input support to Django's form widgets. This has come up many times over the years (#16630, #21470, #33100, #34660, the "Adding SearchInput widget" thread, the django-developers mailing list discussion), and each time the conclusion was that the ecosystem wasn't ready. I believe it is now, and I'd like to address the concerns raised in those earlier discussions.
Responding to earlier concerns
| Concern (from earlier threads) | Response |
|---|---|
| Cross-browser support isn't there | 97% global support; "Baseline: Widely available" since 2021 |
| Safari doesn't have native pickers | Safari 14.1+ (2021) has full support |
| Localization mismatch (browser uses OS locale, not Django's) | This is by design in the HTML spec. The display follows the user's locale (which is generally what users want), while the value is always ISO 8601. Django's USE_L10N and format settings continue to apply for parsing. |
| Breaking change for existing forms | Opt-in only (False by default), per-widget overridable |
| Custom JS pickers will conflict | Only affects projects that enable the setting. The admin's JS already handles this gracefully. |
| Styling the native picker is limited | True, but this is the trade-off for platform-native UX. Projects needing full styling control can keep type="text" and use a JS library. |
| Accessibility concerns | Native inputs are at least as accessible as the current JS widgets, and improving with every browser release. See the accessibility section below. |
The proposal
Add a new USE_HTML5_DATE_INPUT setting (default False) that, when enabled, makes DateInput, TimeInput, and DateTimeInput render as <input type="date">, <input type="time">, and <input type="datetime-local"> respectively, instead of <input type="text">.
A working implementation is available on my ticket-37083 branch (diff with main branch here). Here's the gist of the approach:
DateTimeBaseInput.__init__()checks the setting and switchesinput_typeaccordingly.- When HTML5 types are active, values are always formatted in ISO 8601 (as required by the HTML spec):
YYYY-MM-DDfor dates,HH:MM:SSfor times,YYYY-MM-DDTHH:MM:SSfor datetimes. - For
timeanddatetime-local, astep="1"attribute is added automatically so browsers display and accept seconds (without it, most browsers only show hours and minutes, silently discarding seconds). DATETIME_INPUT_FORMATSis extended withT-separator variants (%Y-%m-%dT%H:%M:%S, etc.) so that values submitted by<input type="datetime-local">are parsed correctly out of the box.- The
typeattribute can always be overridden per-widget viaattrs={"type": "text"}, regardless of the global setting.
In the Django admin, enabling this setting naturally replaces the JavaScript-based calendar and clock popups with native browser pickers — the admin's DateTimeShortcuts.js only attaches to type="text" inputs.
Cross-browser support is ready
The recurring blocker in previous discussions was inconsistent browser support, particularly Safari and older Firefox lacking native picker UIs.
That is no longer the case. According to Can I Use, <input type="date">, <input type="time">, and <input type="datetime-local"> now have ~97% global support (89.6% full + 7.1% partial). MDN classifies all three as "Baseline: Widely available" since 2021. Specifically:
- Chrome / Edge: Full support since Chrome 25 / Edge 13.
- Firefox: Full support since version 93 (2021).
- Safari (desktop): Full support since 14.1 (2021).
- iOS Safari / Android: Excellent support with native mobile pickers.
The "partial support" in the Can I Use numbers mostly refers to minor UI inconsistencies (e.g. the exact picker styling), not functional gaps. All major browsers now submit the correct ISO-format value and display a functional picker UI.
This is comparable to (or better than) the support level for <input type="email"> and <input type="url">, which Django adopted as defaults back in 1.6 (#16630).
Accessibility
Accessibility was raised as a concern in the SearchInput thread, referencing a 2019 Hassell Inclusion analysis that found native date pickers had poor screen reader support. That analysis is now 7 years old, and browser accessibility has improved substantially since then. Current state:
- NVDA + Firefox/Chrome (Windows): Announces label, spin buttons for day/month/year, and current values. Calendar grid navigation works with reasonable announcements.
- JAWS + Chrome/Edge (Windows): Functional, with some formatting quirks in announcements (AT behavior, not author markup errors).
- VoiceOver + Safari (macOS): The weakest combination, with known issues around label association and picker announcements, but functional for basic date entry.
- Mobile (TalkBack / VoiceOver): Native mobile date pickers (wheels/reels) are generally well-supported.
Importantly, native date inputs are at least as accessible as Django's current JavaScript calendar/clock widgets, which have their own well-documented accessibility problems: they have historically lacked aria-label attributes on buttons, did not manage focus into the popup, and had no keyboard trap for the dialog.
Recent work on the existing admin widgets has improved this baseline:
- #36459 (merged): Added
aria-labelattributes to all buttons in the admin calendar and clock widgets. - #36458 (ready for checkin): Moves focus into the popup dialog when opened.
These improvements make the current JS widgets better than they were, but native HTML5 inputs still carry advantages: they use the browser's built-in accessibility tree, respond to OS-level accessibility settings, and are continuously improved by browser vendors without Django needing to ship fixes. The opt-in nature of this proposal means projects with strict accessibility requirements can choose whichever approach works best for their audience.
Touch-friendly / mobile UX
This is arguably the strongest motivation. Native date/time inputs provide platform-native pickers on mobile:
- iOS shows the familiar scroll wheel picker.
- Android shows a material-design calendar/clock.
These are far more usable on touch devices than Django's current JS calendar popup, which was designed for desktop mouse interaction. The Can I Use data shows that mobile is where support is most complete and mature.
Many Django forum threads (example 1, example 2) show developers seeking exactly this behavior, typically implementing the same 3-line widget subclass workaround that Django could provide out of the box.
Backwards compatibility
This is the most important concern, and the proposal is designed to be conservative:
-
Opt-in by default:
USE_HTML5_DATE_INPUT = Falsemeans zero change for existing projects. No existing form, template, or JavaScript breaks unless a developer explicitly enables it. -
Per-widget override: Even with the setting enabled, any widget can opt out via
attrs={"type": "text"}. This gives granular control for mixed scenarios. -
Less common formats: When the setting is enabled, values are always formatted as ISO 8601 for rendering (as the HTML spec requires). However:
DATE_INPUT_FORMATS,TIME_INPUT_FORMATS, andDATETIME_INPUT_FORMATScontinue to work for parsing submitted values, so server-side processing is unaffected.- If a developer has set an explicit
format=on a widget, that format is respected even when HTML5 types are active. This means custom formatting still works, though the native picker UI may not display it as expected (this is inherent to how<input type="date">works — the browser controls the display format based on the user's locale). - The
T-separator datetime formats (%Y-%m-%dT%H:%M:%S, etc.) are added toDATETIME_INPUT_FORMATSsodatetime-localsubmissions parse correctly without any configuration.
-
Admin integration: The admin's
DateTimeShortcuts.jsalready checksinput.typeand only attaches the JS calendar/clock totype="text"inputs. When HTML5 types are active, the JS popups simply don't appear, and the native pickers take over. No admin template changes are needed. -
Future default change: If this setting proves successful and the community is comfortable with it, a future Django version could consider changing the default to
Truewith a proper deprecation path. But that's a separate discussion.
Summary
The Django community has been asking for this for over a decade (#21470 was filed in 2013). The blockers (browser support, accessibility, and Safari gaps) have been resolved. The proposal is conservative (opt-in, per-widget overridable, no admin changes needed), and the implementation is minimal (~25 lines of widget code + the setting).
I'd appreciate feedback on the approach. The ticket 37083 can be reopened if there is consensus to do something.