Poking at the edges of input number types

November 10, 2022

Sometimes when you think you know...

Working on a spin-selector input for Accessible Web Components, and I wanted to check on the logic of the spinner behaviour for <input type="number">.

<input type="number" min="0" max="10" step="7" value="0"/>

Keep hitting the up button, and the input value will go 0, 7, 7... Which is to be expected.

Weird things happen when you do this, though:

<input type="number" min="0" max="10" step="7" value="12"/>

Hitting in the up button, and the input just sits at 12.

Hitting the down button, though, and the value will progress: 12, 10, 7, 0.

I had expected 12, 5, 5...

<input type="number" min="0" max="10" step="3" value="12"/>

This time, hitting the down button will change the value along this sequence: 12, 10, 9, 6, 3, 0.

For one more test, I tried:

<input type="number" min="2" max="20" step="7" value="40"/>

40, 20, 16, 9, 2.

That's when I realised what was happening...

  1. Start with number greater than the maximum.
  2. Hitting the down button will set the value to be the maximum.
  3. Hitting the down button again will set the value to the highest multiple of the step (plus the minimum) below the maximum.

One last stab:

<input type="number" min="2" max="20" step="7" value="3"/>

Hitting up this time: 3, 9, 16...

I'm not surprised that this is how it works - although it did invalidate the mental model I had 30 minutes ago when thinking about these edge cases for the spin-selector.

Which goes to show - sometimes when you think you know, it's still good to check.