Open zachleat opened 8 years ago
Works as expected in Safari 7.
More useful discussion from @dmethvin here: https://twitter.com/davemethvin/status/751107262471606272
So the problem is that Safari 6 stores and displays the floating-point value rather than the string value, even though the unrounded string is a valid floating-point number per the html 5 spec (and thus can be kept as a string and converted to a rounded double-precision float when needed)? Browser bug sounds about right, maybe even browser quirk.
I believe that the browser should not be doing this per spec; however, note that this kind of use of <input type="number">
is invalid:
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. A simple way of determining whether to use type=number is to consider whether it would make sense for the input control to have a spinbox interface (e.g. with "up" and "down" arrows). Getting a credit card number wrong by 1 in the last digit isn't a minor mistake, it's as wrong as getting every digit incorrect. So it would not make sense for the user to select a credit card number using "up" and "down" buttons. When a spinbox interface is not appropriate, type=text is probably the right choice (possibly with a pattern attribute).
https://html.spec.whatwg.org/multipage/forms.html#number-state-(type=number)
Yeah, the docs seem pretty clear. If you actually want an IEEE floating point value out of the process this bug doesn't make that much difference. Trying to use a type=number
input for other purposes is also risky since user input like "9e9" is valid.
Good conversation, thanks for chiming in. Really, the root problem is Android won't show the numeric keypad on Android unless it's a type of number
- neither pattern="[0-9]*"
(any pattern in fact) or inputmode="numeric"
trigger the right keypad (thanks Google!).
So to launch the optimal keypad on Android, we've been trying to make the type=number
work for us and there are lots of interesting issues like non-numeric characters can break the input in Firefox so we're filtering out any characters that aren't 0-9, etc. to avoid the situation @dmethvin (hi!) brought up. Yes, we know that the spec designed this only for capturing floating point values but we really want to have a decent UX for data entry and Android isn't doing us any favors.
You can get rid of the spinner buttons with this CSS on webkit and FF with a bit of CSS:
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;
}
And we've added extra JS to ignore the arrow keys and other triggers that would increment/decrement the value. Fun!
Let's just say this is a messy situation. But I don't think the other answer (use tel
) is any good either, at least semantically.
Thanks for the detailed explanation @toddparker! Yeah this seems like the perfect place to apply that inputmode=numeric
attribute that nobody implements yet.
Just for fun, I wanted to see if the latest Android (6) finally supported inputmode http://jsbin.com/cukeha/
Nope:
Good ol number works tho:
Using tel
just seems like such a bad option, even if it's more accepting of values. The keypad looks like a dialer rather than a numeric keypad here on latest Android which is confusing UX-wise
Additional Safari 6 test data (note that this input is only 16 digits long and is still rounded)
I'm pretty sure this is expected: double (64-bit float) can't store that much precision, only 52 bits of precision. That's between 15 and 17 decimal digits.
Worse, this doesn’t seem to be feature testable, given the following:
el.value = "12341234123412341234"
;12341234123412300000
el.value
returns 12341234123412341234
el.valueAsNumber
returns 12341234123412340000
(note the four trailing zeros, as opposed to the five rendered trailing zeros above). This behavior is consistent cross-browser, even on browsers that don’t exhibit this truncating issue in the UI (Chrome).Note that Firefox 47 exhibits the same behavior for the above feature test attempt, however operates correctly from a UX perspective: typing 12341234123412341234
manually into the field renders correctly.
More test data here:
value
matches?valueAsNumber
matches? If does not match and rendered value also does not match, are they the same?Using the value "12341234123412341234"
take the following two paths: setting value
with JS or a user entered value. Interesting bullets are bolded.
value
with JS:12341234123412300000
value
matchesvalueAsNumber
mismatch and does not match rendered value: 12341234123412340000
Feature test would not work.
12341234123412300000
value
mismatch: 12341234123412340000
valueAsNumber
mismatch and does not match rendered value: 12341234123412340000
12341234123412340000
value
with JS:12341234123412300000
(Bugzilla Issue)value
matchesvalueAsNumber
mismatch and does not match rendered value: 12341234123412340000
Feature test would not work.
value
matchesvalueAsNumber
mismatch: 12341234123412340000
value
with JS:value
matchesvalueAsNumber
mismatch: 12341234123412340000
value
matchesvalueAsNumber
mismatch: 12341234123412340000
Verdict: close but valueAsNumber should probably be NaN
value
with JS:value
matchesvalueAsNumber
mismatch: NaN
value
matchesvalueAsNumber
mismatch: NaN
Verdict: this is how it should work in all browsers
FWIW per spec valueAsNumber should be converted to a floating point number (so by your account "incorrect") whereas value should just be the typed string.
@domenic Ah yeah, sorry. Will correct it to say “mismatched” instead of “incorrect”
.value = "12341234123412341234";