Skip to content

About

JavaScript duration input with a fixed HH:mm:ss.SSS display, millisecond precision, and support for durations over 24 hours.

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Repository files navigation

npm bundle size Contributors Forks Stargazers Issues MIT License RepoSize Build StatusDIY Build StatusDIY


Logo

A compact duration input with a fixed, locale-independent display for hours, minutes, seconds, and milliseconds.

Use input-duration when users need to enter a duration rather than a time of day: for example, a countdown, elapsed-time limit, or media offset. Its displayed value uses HH:mm:ss.SSS on every locale, without a locale-specific AM/PM presentation, and supports durations greater than 24 hours (currently up to 99 hours) with millisecond values, such as 30:00:00.125.

HTML's built-in <input type="time"> is for choosing a time of day, not entering elapsed time. HTML does not provide a native duration input with a fixed HH:mm:ss.SSS format or support for values over 24 hours; this web component fills that gap.

The component supplies its own segmented layout instead of the browser's native time-picker UI, so the displayed format does not change with browser or locale. It is built from native number inputs, however, so details such as the on-screen keyboard and interaction can still vary by device and browser; this is consistency of the value's presentation, not a guarantee of pixel-identical rendering. Milliseconds can be entered as three digits; the input's step controls increment in 10 ms intervals.

The control's styles are scoped inside its Shadow DOM, so global styles and resets from Tailwind or other CSS libraries do not leak into its internal layout. The control inherits its font and text color from its surrounding page.



Fixed-format duration input

input-duration is intended for touch and keyboard use. The HTML structure and displayed field order are controlled by the component; device-specific input and keyboard behavior remains native to the browser.

Bob is rescued by INPUT-DURATION!

The goal is a small JavaScript duration input that gives countdowns and elapsed-time entry a predictable displayed format across browser and locale settings, while retaining native numeric inputs for editing.

Does this lose any functionality? No! document.querySelector('#bob').value has a getter and setter, so values can be set and retrieved from JavaScript or the HTML attribute.

Screenshots

The desktop comparisons show how a native time input represents a time of day, while input-duration displays an elapsed duration in a fixed format.

💔 the native time input on the left; 🏁 `input-duration` is shown on the right.

Chrome

Chrome comparison of a native time input and input-duration

Safari

Safari comparison of a native time input and input-duration

The mobile screenshots show the native time picker alongside input-duration on each platform.

Device 💔 Native time input
🏁 input-duration
Android Android native time picker input-duration on Android with the numeric keyboard
iOS iOS native time picker input-duration on iOS with the numeric keyboard

Native time inputs are useful when the user is choosing a time on a clock. A duration is different: 30:00:00.125 means thirty hours, not 6 AM the next day. Keeping those concepts separate avoids date, timezone, and 12/24-hour display concerns when collecting a duration.

Here's why:

  • Enter durations independently of a calendar date or time of day.
  • Keep a fixed HH:mm:ss.SSS display regardless of locale-specific clock conventions.
  • Represent durations beyond 24 hours (up to 99 hours in the current implementation).
  • Read and set the value from JavaScript using the component's .value property.
Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. Roadmap
  5. Related duration controls
  6. Future partners
  7. Cross-browser testing
  8. Contributing
  9. License
  10. Contact
  11. Acknowledgments

About The Project

HTML's <input type="time"> represents a time of day. Browsers may localize its visible control (for example, showing a 12-hour clock with AM/PM), even though its value is standardized. It also cannot represent a duration longer than a day.

input-duration is for duration values, not appointments or clock times. Its separate numeric fields present hours, minutes, seconds, and milliseconds in a fixed HH:mm:ss.SSS format. This avoids locale-dependent time-of-day presentation while allowing durations beyond 24 hours and millisecond values in a compact control.

drawing

(back to top)

Built With

input-duration is a module and works with webpack. Any add-ons/plugins used in dev are in the acknowledgements section.

(back to top)

Getting Started

There are no pre-requisites for using input-duration if you're not compiling/ packaging you javascript. If you are packaging:

Prerequisites

This is an example of how to get started with npm and webpack, other frameworks should work too.

  • npm & webpack
    npm install npm@latest -g
    npm init -y
    npm install webpack webpack-cli --save-dev

Installation

With packaging: This template doesn't rely on any external dependencies or services.

  1. Install from NPM
 npm i input-duration
  1. import input-duration in javascript
import id from 'input-duration';

Without packaging:

  1. Add script:
<script type="module">

import id from 'https://cdn.jsdelivr.net/npm/input-duration/+esm'
       
</script>
 

(back to top)

Usage

input-duration requires a <input-duration> element . There's no more HTML than that, but don't forget the closing tag. Native Input elements don't have them!

<input-duration id='bob'></input-duration>

Individual duration fields can be hidden with boolean attributes:

<input-duration no-hours no-minutes no-seconds no-microseconds></input-duration>

Use hideHours(), hideMinutes(), hideSeconds(), and hideMicroSeconds() to hide fields, and the corresponding show*() methods to show them again. The existing noHours(), noMinutes(), noSeconds(), and noMicroSeconds() methods remain available as aliases for the hide*() methods. Hidden fields do not change the component's HH:mm:ss.SSS value format.

Customize the separators with the hours-divider, minutes-divider, seconds-divider, and microseconds-divider attributes. The first three replace the separators between fields; microseconds-divider adds an optional suffix after milliseconds. For example:

<input-duration hours-divider="h " minutes-divider="m " seconds-divider="s " microseconds-divider="ms"></input-duration>

The equivalent methods are setHoursDivider(text), setMinutesDivider(text), setSecondsDivider(text), and setMicroSecondsDivider(text). Pass text as a string; it is rendered as text, not HTML. Remove an attribute to restore its default separator (or remove the milliseconds suffix).

If you would like to get or set values or to disable input-duration elemet, javascipt can do that:

document.querySelector('#bob').value = '44:04:04.444'

Bootstrap styling

The component keeps its Shadow DOM, so Bootstrap's CSS selectors do not directly style its internal fields. Instead, map Bootstrap theme variables to the component's CSS custom properties. This is additive: without overrides, the component retains its default appearance.

input-duration {
  --input-duration-border-color: var(--bs-border-color);
  --input-duration-border-radius: var(--bs-border-radius);
  --input-duration-background: var(--bs-body-bg);
  --input-duration-color: var(--bs-body-color);
  --input-duration-focus-color: var(--bs-primary);
  --input-duration-focus-outline: 0.25rem solid rgba(var(--bs-primary-rgb), 0.25);
}

The internal control and its fields, dividers, and icon are also exposed as Shadow Parts for targeted styling:

input-duration::part(control) {
  padding: 0.375rem 0.75rem;
}

input-duration::part(field) {
  font-size: 1rem;
}

Available parts are control, field (also field-hours, field-minutes, field-seconds, and field-milliseconds), divider (also divider-hours-minutes, divider-minutes-seconds, and divider-seconds-milliseconds), and icon. Supported CSS custom properties are --input-duration-gap, --input-duration-padding, --input-duration-border-color, --input-duration-border-radius, --input-duration-background, --input-duration-color, --input-duration-focus-color, --input-duration-focus-outline, --input-duration-focus-outline-offset, --input-duration-divider-color, --input-duration-divider-opacity, --input-duration-disabled-color, and --input-duration-icon-color.

and

document.querySelector('#bob').disable()

so the inputs are modified.

For the generated JSDoc API reference, see the input-duration API documentation.

(back to top)

Roadmap

  • Emperically determine behaviour of Input (time) on Chrome
  • Reverse engineer input behaviour (arrows, digits, 0 addition, etc.)
  • Cross browser/ cross os manual tests
  • Add end to end multi-browser, multi-os Selinium tests
  • Update demo page (either PM.com or JSfiddle type)
  • Multi-language documentation (Google translate of this page?)
    • Chinese
    • Spanish

2026

  • Document and verify a versioned Chrome <input type="time"> behavior profile: compare the WHATWG standard with Blink's implementation and time-input tests (including multiple-field UI tests). Record Chrome version, OS, and locale; verify relevant keyboard and segment-editing behavior, then adapt input-duration where appropriate without assuming platform-specific time-picker UI is universal.
  • Add configurable duration segments and presentation, including optional days, hiding units, and custom dividers. Keep HH:mm:ss.SSS as the default. (html-duration-picker.js, input-duration-element)
  • Support declarative minimum and maximum values with consistent validation and boundary behavior. (html-duration-picker.js)
  • Improve accessibility with per-segment labels, group semantics, and documented screen-reader and keyboard behavior. (time-input-polyfill demonstrates accessible time-field interactions.)
  • Participate in native HTML forms, including named submission, required/validity, disabled state, and form reset/restore behavior. (duration-input example)
  • Offer optional ISO 8601 duration serialization and Temporal.Duration interoperability without breaking the existing HH:mm:ss.SSS value format. (WHATWG discussion, duration-input example)

See the open issues for a full list of proposed features (and known issues).

(back to top)

Related duration controls

This comparison summarizes capabilities described in each project's documentation; a dash means the feature is not documented, not necessarily unsupported. "Estimated users" is approximated by npm package downloads from 2026-10-28 through 2026-11-03, not unique people; downloads can include CI, repeated installs, and automated systems, and omit CDN or other use. The Wigny entry is a gist example rather than a maintained library, so no npm download figure is available.

Control Display / units Value representation Bounds Precision / interaction Estimated users*
input-duration Fixed HH:mm:ss.SSS (00–99 hours); noHours() can hide hours HH:mm:ss.SSS string via .value No public min/max options documented Milliseconds; digit entry, arrow navigation and increment ~748
timepoint-selection Selectable dd:hh:mm:ss, dd:hh:mm, hh:mm:ss, hh:mm, or mm:ss; custom unit labels Numeric seconds through getValue() / setValue() Configurable maximum / rollover Seconds; keyboard navigation, arrow increments, rollover ~22
html-duration-picker.js HH:MM:SS; optional hidden seconds Formatted text in an enhanced native <input> Configurable minimum and maximum durations Seconds in documented formats; interaction details not specified ~905
muan/input-duration-element Hours, minutes, seconds; customizable dividers/slots Numeric seconds; value and change event max documented; min and validation listed as TODOs Demo covers durations up to 180 seconds; precision beyond seconds not specified ~9
segmented-input Duration preset or custom parsing/formatting and segments Formatted string in an enhanced native <input> Per-segment min, max, and step; custom validity Duration preset shown to seconds; arrow-key segment navigation and adjustment ~4
Wigny duration-input example Markup-defined hour, minute, and second segments ISO 8601 duration string; form-associated custom element No public min/max API documented Fractional seconds; keyboard segment navigation and adjustment N/A (gist)

These projects illustrate possible directions—such as optional units, configurable formatting, bounds, alternate value formats, and native form participation—without implying that every feature is a fit for input-duration.

(back to top)

Future partners

Potential integration targets only; these projects are not affiliated with or endorsing input-duration.

  • React Hook Form — provide a tested Controller adapter/example that synchronizes the custom element's value, events, ref, and validation.
  • Formik — add a custom Field example to connect duration values to Formik-managed forms.
  • Angular Reactive Forms — provide a ControlValueAccessor adapter for model-to-view updates, user changes, touched state, and disabled state.
  • Shoelace — document how to use the framework-agnostic duration element alongside Shoelace form controls in a consistent design system.

(back to top)

Cross-browser testing

The browser and device results linked below are historical and should not be treated as verification against current browser versions. The local regression suite checks component behavior, but current cross-browser rendering and interaction still need to be tested.

Tests & Live Status

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

Run the local regression tests with npm test.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

(back to top)

License

Distributed under the MIT License. See LICENSE.txt for more information.

(back to top)

Contact

Stephan Luis - stephan@learnsense.org

Project Link: https://github.com/StephanLuis/input-duration

(back to top)

Acknowledgments

Resources I've found helpful and would like to give credit to:

(back to top)

About

JavaScript duration input with a fixed HH:mm:ss.SSS display, millisecond precision, and support for durations over 24 hours.

Topics

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages