SendForm.net

HTML Date Input: What Browsers Actually Render

An HTML date input is one line of markup, but what your visitor gets depends on their browser, operating system and language settings. Here is what each browser renders, what the form really submits, and where the control falls short.

Sophie ParkerPublished · Updated · 9 min read
The same HTML date input rendered as three different date pickers on a desktop browser, a laptop and a phone
Key takeaways The short version, before the details.
  1. Every browser draws its own date picker, and you cannot replace or restyle the calendar itself.
  2. The date shown on screen follows the visitor's locale, but the submitted value is always yyyy-mm-dd.
  3. min, max and step limit the choice in the browser only, so the server still has to check the date.

What does an HTML date input render in each browser?

The html date input renders a native date control that the browser, not your page, designs. On desktop that is usually a segmented field (day, month, year) with a calendar popup. On phones it is the system date picker.

The markup is the same everywhere:

<label for="start">Start date</label>
<input type="date" id="start" name="start">

What appears is not:

BrowserWhat the visitor seesTyping by keyboard
Chrome and Edge (desktop)Segmented field with a calendar icon that opens a popup calendarYes, segment by segment
Firefox (desktop)Segmented field with its own calendar popup and a clear buttonYes, segment by segment
Safari (macOS, 14.1 and later)Segmented field that opens a small calendar popoverYes, segment by segment
Safari (iPhone and iPad)A tappable field that opens the iOS system pickerNo, picker only
Chrome (Android)A tappable field that opens the Android calendar dialogDepends on the system dialog
Very old browsersA plain text box, because unknown types fall back to type="text"Free text, any format

The behaviour is defined in the HTML Standard, which fixes the value format but leaves the user interface to each browser. That is why two visitors can fill in the same field in very different ways.

What input type date does not support

  • Placeholder. The placeholder attribute is ignored. The browser shows its own format hint, such as mm/dd/yyyy.
  • Pattern and maxlength. Neither applies to input type date. The control already enforces the format.
  • A custom calendar design. The popup belongs to the browser or the operating system.

Which HTML date format is shown and which is submitted?

There are two formats, and mixing them up causes most date bugs. The displayed format follows the visitor's browser and system locale. The submitted html date format is always yyyy-mm-dd, with a four digit year and zero padded month and day.

What visitors see

  • United States10/06/2026
  • United Kingdom06/10/2026
  • Germany06.10.2026
  • Japan2026/10/06

What the form submits

2026-10-06

The same string in every browser and every locale.

The same rule applies to the attributes. value, min and max must all be written as yyyy-mm-dd. A value in any other format is treated as empty.

<input type="date" name="start" value="2026-10-06">

Can you change the display format of a date input?

No. There is no attribute, CSS property or JavaScript option that changes the format a date input displays. It follows the browser's locale, which is not always the language of your page.

If you must show one fixed format to everyone, such as dd/mm/yyyy, you need separate fields or a JavaScript picker instead of the native control.

How to read a date input value in JavaScript

The value property returns the yyyy-mm-dd string, or an empty string when the field is empty or incomplete. Be careful when you turn it into a Date:

const input = document.querySelector('#start');

input.value;        // "2026-10-06"
input.valueAsDate;  // Date at midnight UTC

// Parsed as UTC, so it can print the day before
// in time zones behind UTC:
new Date(input.value).toLocaleDateString();

// Local midnight instead:
const [y, m, d] = input.value.split('-').map(Number);
const local = new Date(y, m - 1, d);

Off by one day? A date-only string is parsed as midnight UTC. In a time zone behind UTC, printing it in local time shows the previous day. Keep the string as a string for as long as you can.

How to limit dates with min, max and step

Three attributes restrict what a visitor can pick. All of them take values in the submitted format.

<input type="date" name="checkin"
       min="2026-10-06" max="2026-12-31" required>

<!-- Only every 7th day, counted from min -->
<input type="date" name="delivery"
       min="2026-10-05" step="7">
  • min and max set the earliest and latest allowed date. Desktop pickers usually grey out the days outside the range.
  • step is counted in days. step="7" with a Monday as min allows Mondays only.
  • required blocks an empty field. Its limits are covered in our guide to the HTML required attribute.

Do not rely on the picker alone. Some pickers, mobile ones in particular, still let people select a date outside the range, and a typed date can be out of range too. The browser then flags the field as invalid on submit.

Set a max even when you do not need one. Without it, Chrome lets visitors type a six digit year, which is easy to do by accident. max="9999-12-31" keeps the year to four digits.

How to set today as the minimum date

HTML has no keyword for today. Set the attribute on the server when you render the page, or with a short script:

const input = document.querySelector('#checkin');
const now = new Date();
const pad = (n) => String(n).padStart(2, '0');

input.min = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;

This builds the date from local parts on purpose. toISOString() returns the UTC date, which can already be tomorrow or still yesterday for your visitor.

How is input type datetime-local different?

input type datetime-local adds a time to the date in a single control. The submitted value looks like 2026-10-06T14:30: date, the letter T, then a 24 hour time.

<label for="slot">Appointment</label>
<input type="datetime-local" id="slot" name="slot"
       min="2026-10-06T09:00" max="2026-10-31T17:00">

Three things differ from the plain date input:

  • No time zone. "Local" means the value carries no offset at all. 2026-10-06T14:30 is half past two wherever the visitor happens to be. If the moment matters, collect or record the time zone separately and convert on the server.
  • Step is in seconds. The default is 60, so no seconds are shown. step="900" gives 15 minute slots, and a step below 60 adds a seconds segment.
  • Support arrived later. Firefox only added it in version 93 and desktop Safari in 14.1, and the time part of the picker varies more between browsers than the calendar does.

MDN documents the exact value rules for both type date and type datetime-local. The older type="datetime", which did include a time zone, was removed from HTML and should not be used.

Can you style a date picker in HTML and CSS?

Partly. You can style the field like any other input: font, padding, border, radius, colours. The popup calendar of a native date picker in HTML cannot be styled at all.

Chromium browsers and Safari expose a few pseudo-elements for the inside of the field:

/* The field itself: works everywhere */
input[type="date"] {
  font: inherit;
  padding: 8px 12px;
  border-radius: 8px;
}

/* The calendar icon: Chromium and Safari only */
input[type="date"]::-webkit-calendar-picker-indicator {
  cursor: pointer;
  opacity: 0.7;
}

/* Ask for the browser's dark version of the control */
input[type="date"] {
  color-scheme: dark;
}

These -webkit- selectors are not standard and Firefox ignores them, so treat them as a bonus, not a design foundation.

How to open the date picker from your own button

Modern browsers support showPicker(), which opens the native picker from a script. It only works in response to a user action such as a click.

const input = document.querySelector('#start');
const button = document.querySelector('#open-calendar');

button.addEventListener('click', () => {
  if ('showPicker' in input) {
    input.showPicker();
  } else {
    input.focus();
  }
});

When is the HTML5 date input the wrong choice?

The html5 date input is a good default for dates near today: a booking, a deadline, a delivery day. On phones it is hard to beat, because the system picker is familiar and needs no extra code. More on that in our guide to mobile form design.

It fits poorly in a few cases:

  • Dates people know by heart. For a date of birth, paging back decades in a calendar is slower than typing. Three plain fields for day, month and year work better, and the GOV.UK Design System recommends exactly that pattern.
  • Date ranges. There is no native range picker. Use two date inputs and set the min of the second from the first.
  • Unavailable days. You cannot disable single dates, weekends or holidays. Only min, max and step exist.
  • A fixed display format or a branded calendar. Both need a custom component.
  • Approximate dates. For "month and year" use two selects. type="month" exists but is not supported as a real picker in every desktop browser.

Why a date input still needs server validation

A date input guarantees nothing about what reaches your server. An old browser sends free text, a script can post anything to your endpoint, and min and max are only checked in the browser. The general rule is covered in our guide to HTML form validation, and for dates it comes down to two checks:

  1. The string matches yyyy-mm-dd exactly.
  2. It is a real calendar date. 2026-02-30 matches the pattern and still does not exist.

Then apply your own business rules, such as "not in the past", on the server as well.

This is what SendForm does for you in its online form builder. The Date question renders a native input type="date", so visitors get the picker their device already knows. When the answer arrives, the server checks both the yyyy-mm-dd pattern and that the date exists, and rejects the answer if either check fails. Time is a separate question type with its own check.

If you already have your own HTML form, you can keep its date fields as they are and point the form at a SendForm contact form endpoint. No server code is needed to receive the submission.

An online form with a date question and an open calendar picker
SendForm online forms

Need a date field that is checked on the server too?

Add a Date question to a hosted form. Visitors get their device's native picker and every answer is validated as a real date before it is saved.

Build a formFree to start

Frequently asked questions

You cannot. The displayed format of a native date input follows the visitor's browser and system locale, and no attribute or CSS property overrides it. The submitted value is always yyyy-mm-dd. To force dd/mm/yyyy for everyone, use three separate fields for day, month and year, or a JavaScript date picker.

Set the value attribute to today's date in yyyy-mm-dd format. HTML has no keyword for today, so write it on the server when the page is rendered or set input.value with JavaScript. Build the string from the local year, month and day, because toISOString() returns the UTC date, which can differ.

That hint is drawn by the browser to show the expected order of day, month and year for the visitor's locale. It is not a real placeholder, and the placeholder attribute has no effect on a date input. The hint changes with the browser language, so another visitor may see dd/mm/yyyy or a translated version.

Not with HTML alone. The native control only understands min, max and step, so you can set a range or allow every seventh day, but you cannot block single dates. Check the chosen date with JavaScript and call setCustomValidity() to show an error, and repeat the same rule on the server.

No. The value is a date and a time, such as 2026-10-06T14:30, with no offset or zone name. It describes the wall clock time where the visitor is. If you need an exact moment, store the visitor's time zone alongside it or convert the value to UTC before saving.