Is there a consistent way across browsers to hide the new spin boxes that some browsers (such as Chrome) render for HTML input of type number? I am looking for a CSS or JavaScript method to prevent the up/down arrows from appearing.
<input id="test" type="number">
<input type="number" min="4" max="8" />
in Chrome and seeing a typical input field with up and down arrows on the side.
<input type="number" pattern="[0-9]*" inputmode="numeric">
. More info: stackoverflow.com/a/31619311/806956
<input type="text" placeholder="number (digits only)" pattern="[0-9]+" class="validate number-validation" ... >
and using jQuery Validati or similar to handle validation. I haven't tested this approach, which is why this is a comment, rather than an answer.
inputmode
.
This CSS effectively hides the spin-button for webkit browsers (have tested it in Chrome 7.0.517.44 and Safari Version 5.0.2 (6533.18.5)):
input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { /* display: none; <- Crashes Chrome on hover */ -webkit-appearance: none; margin: 0; /* <-- Apparently some margin are still there even though it's hidden */ } input[type=number] { -moz-appearance:textfield; /* Firefox */ }
You can always use the inspector (webkit, possibly Firebug for Firefox) to look for matched CSS properties for the elements you are interested in, look for Pseudo elements. This image shows results for an input element type="number":
https://i.stack.imgur.com/QATjk.png
Firefox 29 currently adds support for number elements, so here's a snippet for hiding the spinners in webkit and moz based browsers:
input[type='number'] { -moz-appearance:textfield; } input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; }
Short answer:
input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } input[type="number"] { -moz-appearance: textfield; }
Longer answer:
To add to existing answer...
Firefox:
In current versions of Firefox, the (user agent) default value of the -moz-appearance
property on these elements is number-input
. Changing that to the value textfield
effectively removes the spinner.
input[type="number"] {
-moz-appearance: textfield;
}
In some cases, you may want the spinner to be hidden initially, and then appear on hover/focus. (This is currently the default behavior in Chrome). If so, you can use the following:
input[type="number"] { -moz-appearance: textfield; } input[type="number"]:hover, input[type="number"]:focus { -moz-appearance: number-input; }
Chrome:
In current versions of Chrome, the (user agent) default value of the -webkit-appearance
property on these elements is already textfield
. In order to remove the spinner, the -webkit-appearance
property's value needs to be changed to none
on the ::-webkit-outer-spin-button
/::-webkit-inner-spin-button
pseudo classes (it is -webkit-appearance: inner-spin-button
by default).
input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
It's worth pointing out that margin: 0
is used to remove the margin in older versions of Chrome.
Currently, as of writing this, here is the default user agent styling on the 'inner-spin-button' pseudo class:
input::-webkit-inner-spin-button {
-webkit-appearance: inner-spin-button;
display: inline-block;
cursor: default;
flex: 0 0 auto;
align-self: stretch;
-webkit-user-select: none;
opacity: 0;
pointer-events: none;
-webkit-user-modify: read-only;
}
According to Apple’s user experience coding guide for mobile Safari, you can use the following to display a numeric keyboard in the iPhone browser:
<input type="text" pattern="[0-9]*" />
A pattern
of \d*
will also work.
I found a super simple solution using
<input type="text" inputmode="numeric" />
This is supported in most browsers:
https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode
https://caniuse.com/input-inputmode
Try using input type="tel"
instead. It pops up a keyboard with numbers, and it doesn’t show spin boxes. It requires no JavaScript or CSS or plugins or anything else.
type=number
does.
Only add this css to remove spinner on input of number
/* For Firefox */
input[type='number'] {
-moz-appearance:textfield;
}
/* Webkit browsers like Safari and Chrome */
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
If you are trying to hide controls the browser adds, it should be a hint that you are misusing that input type.
Standard Conformance Issues
From the HTML spec on type=number:
The type=number state is not appropriate for input that happens to only consist of numbers but isn't strictly speaking a number. For example, it would be inappropriate for credit card numbers or US postal codes.
(Emphasis is mine)
Usability Issues
The <input type=number>
was found to be problematic during a usability study performed by the GOV.UK team. This team maintains one of the world's best known design systems and concludes that this input type:
cannot be dictated or selected when using Dragon Naturally Speaking appears as unlabeled in NVDA's element list appears as a spin button in NVDA's object navigation, which has an edit field and two buttons inside - those buttons are unlabeled, but decrease/increase the value is reported as unlabeled edit field when using nvda+tab
Alternative Solution
Instead, they recommend to use <input type="text" inputmode="numeric" pattern="[0-9]*">
which comes down to the combined answers of @team_steve and @youjin. This not only hides the spin boxes, it also improves the overall usability of the element.
It comes without saying that additional validation needs to be done, along with a helpful error text.
1K
, they mean 1000
. But if the K
can't be typed in, you cannot detect this mistake. The input will be 1
, which is not what was meant.
<form>
elements, validation needs to be implemented anyway. And an appropriate error message will be way more user friendly than messing with the user’s input. You got the evidence right in the links.
I've encountered this problem with a input[type="datetime-local"]
, which is similar to this problem.
And I've found a way to overcome this kind of problems.
First, you must turn on chrome's shadow-root feature by "DevTools -> Settings -> General -> Elements -> Show user agent shadow DOM"
Then you can see all shadowed DOM elements, for example, for <input type="number">
, the full element with shadowed DOM is:
https://i.stack.imgur.com/wIu6b.png
And according to these info, you can draft some CSS to hide unwanted elements, just as @Josh said.
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type=number] {
-moz-appearance: textfield;
}
Not what you asked for, but I do this because of a focus bug in WebKit with spinboxes:
// temporary fix for focus bug with webkit input type=number ui
if (navigator.userAgent.indexOf("AppleWebKit") > -1 && navigator.userAgent.indexOf("Mobile") == -1)
{
var els = document.querySelectorAll("input[type=number]");
for (var el in els)
el.type = "text";
}
It might give you an idea to help with what you need.
This is more better answer i would like to suggest on mouse over and without mouse over
input[type='number'] {
appearance: textfield;
}
input[type='number']::-webkit-inner-spin-button,
input[type='number']::-webkit-outer-spin-button,
input[type='number']:hover::-webkit-inner-spin-button,
input[type='number']:hover::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0; }
In WebKit and Blink-based browsers & All Kind Of Browser use the following CSS :
/* Disable Number Arrow */
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
To make this work in Safari I found adding !important
to the webkit adjustment forces the spin button to be hidden.
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
/* display: none; <- Crashes Chrome on hover */
-webkit-appearance: none !important;
margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
}
I am still having trouble working out a solution for Opera as well.
Maybe change the number input with javascript to text input when you don't want a spinner;
document.getElementById('myinput').type = 'text';
and stop the user entering text;
document.getElementById('myinput').onkeydown = function(e) {
if(!((e.keyCode > 95 && e.keyCode < 106)
|| (e.keyCode > 47 && e.keyCode < 58)
|| e.keyCode == 8
|| e.keyCode == 9)) {
return false;
}
}
then have the javascript change it back in case you do want a spinner;
document.getElementById('myinput').type = 'number';
it worked well for my purposes
On Firefox for Ubuntu, just using
input[type='number'] {
-moz-appearance:textfield;
}
did the trick for me.
Adding
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
Would lead me to
Unknown pseudo-class or pseudo-element ‘-webkit-outer-spin-button’. Ruleset ignored due to bad selector.
everytime I tried. Same for the inner spin button.
I needed this to work
/* Chrome, Safari, Edge, Opera */
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button
-webkit-appearance: none
appearance: none
margin: 0
/* Firefox */
input[type=number]
-moz-appearance: textfield
The extra line of appearance: none
was key to me.
input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none;
For me on chrome nothing has worked but display: none
.
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
display: none;
}
/* Firefox */
input[type=number] {
-moz-appearance: textfield;
}
Credits to @philfreo for pointing it out in the comments.
This like your css code:
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
Success story sharing
display: none;
as the only thing inside the selectortype=number
if you have to hide these arrows. E.g. currently they'd be still displayed in Opera and they'll start being displayed in Firefox, IE etc. when they implement this input type.