I wanted to make a simple time input and not the built-in one which is not consistent on browsers.

I did the following:

#time-input {
  display: flex;
  width: 150px;
  border: 1px solid black;
  border-radius: 8px;
  padding: 3px;

input {
  min-width: 0;
  border: none;

input:focus {
  outline: none;

#hours {
  text-align: right;
<div id="time-input">
  <input type="text" id="hours" maxlength=2 dir="rtl">
  <div id="colon"><span>:</span></div>
  <input type="text" id="minutes" maxlength=2>

Do you think it's alright? Do you have any suggestions for how to improve it? Maybe give it better UX, for example automatically moving between the hours and minutes inputs if you fill one or maybe instead of an actual colon, paint a colon with CSS somehow (If it's even possible), or, anything something else?

  • 1
    \$\begingroup\$ "which is not consistent [across] browsers" Ok, that's fair, I imagine it's true, it probably impacts both UX and testing. But please expand on that motivation. Cite one or more URLs describing the the inconsistencies, or write sentences to that effect. Crucially, we need browser names and versions. Imagine a project adopts this approach, and then Chrome or Firefox improves their time UX a few months from now. How would we know, how would we test, that this is still a better solution? Consistent colon behavior seems relevant. Can a user enter 25:62? It's unclear if this is always better. \$\endgroup\$
    – J_H
    Jul 30, 2023 at 20:09
  • \$\begingroup\$ For me it was that I wanted a 24h format, and in chrome for desktops it shows it as a 12h with am/pm for example \$\endgroup\$
    – pileup
    Jul 30, 2023 at 20:20
  • 2
    \$\begingroup\$ Well, that's a locale thing, right? I mean, European users prolly have language pref set to French or Spanish or whatever, and times come out in 24h format, and currency looks different... That is, the browser is doing what the user asked for. Feel free to offer a replacement. Maybe be explicit, and call it a 24h time widget? \$\endgroup\$
    – J_H
    Jul 30, 2023 at 20:26
  • \$\begingroup\$ Yes I think it's locale related. The problem in my case is that it's an internal system in the organisation and everything related to that is controlled by the IT team. Also regarding invalid time input, I do need to add validation with JS I believe (unless it's possible without, and of course there's more backend validation), and only allow valid time input \$\endgroup\$
    – pileup
    Jul 30, 2023 at 23:17

1 Answer 1


Consider using semantic elements like <fieldset> and <legend> to group the two fields together and to give that grouping a name. Provide labels to the fields using aria-label attributes or actual <label> elements. These adjustments are best practices for accessibility, and will ensure the form is usable for any future members of the IT team who might rely on assistive technologies. See Creating Accessible Forms by WebAIM for more techniques. Additionally, the outline property shouldn't be suppressed because it's how keyboard users know which element is currently focused.

Additionally, setting the type attribute of the inputs to number instead of text will automatically reject any characters not used for number notation, and also allow you to set the range of numbers accepted by each input (0–24 and 0–59) and allow for easier front-end validation.

The user experience could be improved by adding am instructional description to ensure users know to use 24-hour notation instead of 12. If JS isn't used to hop focus from the hour to the minute field, I'd suggest not making it look like one large field and instead keep the hours and minutes as distinct boxes. That will help users know they must focus into one or the other to edit the time and that they can't just type it all at once.

Below is an example with those suggestions—

.custom-time-input { display: inline-block; }
.custom-time-input i { display: block; }
<fieldset class="custom-time-input">
    max="24" />
    max="59" />
  <i id="hour-description">24-hour format</i>


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.