HTML5’s native number picker (
<input[type=number]) and jQuery UI 1.9’s spinner can both be used to create inputs for numeric data. So which makes sense for your application? Let’s start with a brief explanation of each.
HTML5 adds several new valid
type attributes for
<input> elements. One of them,
number, can be used to create a number picker.
This will present the user with a number picker in supported browsers, which, as of this writing includes Chrome, Safari, Opera, iOS, Opera Mobile, and Android 4.0+ (full support list). Here’s what the user will see in supported browsers:
Opera Mobile 12:
Android 4.1 (Jelly Bean):
As you can see one of the nicest effects of using
[type=number] is that mobile users will automatically be presented with a number pad to aid with entry of numeric data. Unsupported browsers will simply treat the
input[type=number] as a normal text input. Firefox has recently added a UI-less version of
input[type=number] to their nightly builds so hopefully a fully enabled version will be coming soon.
You can see what your browser does below:
The native number picker supports
step attributes to allow you to pick the minimum value of the
<input>, the maximum value of the
<input>, and the amount the value should be incremented / decremented when the user spins through values (the
step attribute defaults to
1 if not specified).
For example, on the
<input> below the browser will enforce that the minimum value will be
2, the maximum value will be
20, and the user will step at increments of
You can see how this behaves in your browser below:
Just as a word of warning, Android 4.1 and iOS 5 do not support the
stepUp(n)- Increment the
stepDown(n)- Decrement the
valueAsNumber- Retrieve the
numbervariable (by default retrieving the
jQuery UI Spinner
spinner is a new plugin due for jQuery UI’s 1.9 release (currently in beta). The plugin by default looks and behaves much like the native number picker.
It also supports setting minimum, maximum, and step values through options rather than attributes.
1 2 3 4 5 6 7 8 9 10
Above and Beyond
What really sets jQuery UI’s
spinner apart from the native picker is that it is extensible, customizable, and it brings a number of extra features. Here are some of the additional things that you can do.
spinner takes a
page option that allows you to define how much the
spinner should step when the page down / page up keys are pressed. The example below shows a
spinner with a
step value of
1 and a
page value of
If you want mousewheel support for a
spinner all you need to do is include Brandon Aaron’s mousewheel plugin and you get it automatically! Try it out on any of the
spinner demos on this page.
Ever need to accept currency at certain defined increments? This example shows a
spinner that spins through currency values at $25 increments, all with the same clean API.
The formatting is localized through Globalize.js, therefore, if you want to handle different currencies all you need to do is pass in the appropriate
If you need to accept time data
spinner can be used for that as well.
page option discussed earlier is used nicely here to make the up / down keys control the minutes and the page up / page down keys to controls hours. Try it out on the example above.
24 Hour Times
spinner uses Globalize.js, you’re free to use a time system different than the United States’ nonsensical one.
Time Picker vs.
HTML5 also provides a native time picker (
input[type=time]), but, it has nearly no support, does not yet provide localized formatting, and does not provide the stepping/paging functionality that
spinner has baked in. In the future it might provide a viable native solution, but for now it’s best to stay away.
Extensible and Customizable
spinner is built on top of jQuery UI’s widget factory, it is easily extensible. For example, let’s say you need to build an input that accepts a year in which the modern summer olympics were held. You could do that with the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Now all your olympics pickers in your code base can share the same code!
<input type="number"> vs.
Although jQuery UI’s
spinner is more advanced and customizable, for most simple applications the native number picker will work just fine. If you simply need a field that accepts numeric data there’s no need to bring in
spinner as a dependency. However, if you do need the ability to fine tune the behavior and look of the picker, or if you need consistent UI across all browsers, jQuery UI’s
spinner provides an excellent API to do so.
To summarize the reasons to use the native picker are:
- Easy to implement, simply give an
- There are no dependencies, the number picker is native to the browser.
- Mobile browsers that support the native picker will optimize the touch keyboard for number input.
And the reasons to use jQuery UI’s
- Browser support - The
spinnerwill work all the way back to IE6.
- Extremely customizable and extensible.
- Customizable handling of the page up and page down keys.
- Easily integrated mousewheel support.
- Built in custom types such as currency and time.
- Built in i18n support.
Using jQuery UI’s Spinner to Polyfill
Another option is to use the native HTML number picker when it’s available, and fallback to jQuery UI’s
spinner when it’s not.
1 2 3 4 5 6 7 8
The code to detect
input[type=number] support was taken from another number picker polyfill by jonstipe. It creates an
<input>, changes its
number, and sees if that change actually took effect to determine whether the browser supports the type. You could also use the
Modernizr.inputtypes.number check from Modernizr to achieve the same thing.
spinner plugin is smart enough to look for the
max attributes on the
<input> so you don’t have to pass those in explictly (thanks @bassistance).
Using Spinner and Getting a Number Keyboard on Mobile
If you want to use a
spinner everywhere AND get a number keyboard on mobile things get a little trickier. Mobile browsers look for an
<input> to have
type=number to provide the number keyboard. So you think this would be as simple as creating a
spinner on a
<input[type=number]> node. However, that produces the following on supporting desktop browsers.
Obviously the double arrow UI is less than ideal. So to work around this you simply need to hide or destroy one of the sets or controls… right?
Well it turns out hiding the native arrow controls is difficult because Chrome places the control on the inside of the
<input> and Safari and Opera place it on the outside. Therefore, if you try to adjust the
margin of the
<input> so jQuery UI’s controls overlap the native ones it won’t work in a cross browser friendly way.
Therefore the best approach I’ve came up with is to hide the
spinner’s arrow controls when the browser creates its own.
1 2 3 4 5 6 7
What this does is detect whether the browser supports the
step attribute, if it does it removes jQuery UI’s controls. What does the
step attribute have to do with the arrow controls? Nothing, except that it just happens that the browsers that support the
step attribute also create a native control to do the stepping. Is this going to change in the future? Quite possibly.
So obviously this is not ideal, and probably shouldn’t be used in production code, but it works at the moment. Have a better approach for tackling this problem? Let me know in the comments.
Update (August 26th, 2012)
Commenter amir pointed out the WebKit provides a pseudoclass that you can use to style, and therefore hide the native spin controls.
1 2 3 4 5 6
This solves the issue for Webkit, but this remains an issue for Opera and browsers that add
input[type=number] support in the future.