← Home v1.3.0

Docs / Components / Date picker

Date picker

A dependency-free date picker and pick-up → return date range picker with times, min and max dates, locales and a change event. Dates can be typed or picked. About 5 KB of JavaScript, dark mode ready.

Date picker

Don't use a native <input type="date">, because it looks different in every browser and operating system. Add ace-datepicker.js and a placeholder <div>, and the script builds the field and calendar. Values are sent with the form as hidden inputs in ISO format (2026-10-21, 10:00).

Single date

The field accepts typed dates as DD/MM/YYYY, or the user can click the calendar icon. The calendar has a year list, month arrows, a dot under today, and a raised brand-colour pill for the selected day. Days outside data-min / data-max are crossed out.

Earliest pick-up is today.

Enter the expiry date shown on the licence.

<div class="ace-field">
  <label class="ace-label" for="pickup">Pick-up date</label>
  <div class="ace-datepicker" data-ace-datepicker
       data-id="pickup" data-name="pickup_date" data-min="today"></div>
</div>

Options: data-id (id of the typed input, for the label) · data-name (form field name, ISO value)
         data-value · data-min / data-max ("today" or YYYY-MM-DD)
         data-placeholder · data-locale="sq" · data-invalid · data-disabled

Date range: pick-up → return

For bookings. The calendar opens as a centred dialog with pick-up and return times (typed in 24-hour format and checked as you type). The first click sets pick-up, and hovering a later day previews the range. The second click sets return and fills the band between the two dates.

Value: none yet

<div class="ace-datepicker" data-ace-daterange data-id="period"
     data-start-name="pickup_date"      data-end-name="return_date"
     data-start-time-name="pickup_time" data-end-time-name="return_time"
     data-min="today"></div>

Options: data-start / data-end / data-start-time / data-end-time (initial values)
         data-time="false" (dates only) · data-start-label / data-end-label
         data-clear-label / data-close-label (translations) · data-placeholder

// Listen for changes
el.addEventListener('ace:change', e => console.log(e.detail))
// → { start: '2026-10-21', end: '2026-10-25', startTime: '10:00', endTime: '10:00' }

// Markup added after page load (Vue / React / HTMX):
AceDatePicker.init(container)
Do
  • Use the range picker whenever a booking has both a pick-up and a return date.
  • Set data-min="today" on booking dates so past days are crossed out.
  • Pass data-locale so month and weekday names match the site language.
Don't
  • Use <input type="date"> or type="time". They look different in each browser, and many show 12-hour AM/PM times.
  • Put two single pickers side by side for pick-up and return. Use the range picker, which shows the whole period.

Use it

One stylesheet and one script from the CDN, pinned to v1.3.0:

<link rel="stylesheet" href="https://acecss.dev/v1.3.0/ace.min.css"
      integrity="sha384-zHAwOqjifsc0D+iUvzD1a4W0R2g0BOK9AqQJZGakUEp/Tm5IUcP07R9xkY0q/stj" crossorigin="anonymous">
<script src="https://acecss.dev/v1.3.0/ace-datepicker.min.js" defer
        integrity="sha384-al9SmJzBEkQvLjq3F7lSGkJUmv2DPLd+1HMRRktG/ms/mFfQTFLOG+WQIGCNufon" crossorigin="anonymous"></script>

Or from npm:

npm i @acecss/core

import '@acecss/core'
import '@acecss/core/datepicker'

Bundlers, Tailwind, every script in one file and self-hosting: Install.

More components