top | item 22433654

Why the Gov.uk Design System team changed the input type for numbers

556 points| joelanman | 6 years ago |technology.blog.gov.uk | reply

173 comments

order
[+] ChrisSD|6 years ago|reply
In summary the main issue is that, according to the spec, `<input type="number">` is only for numbers that are going to be parsed into a Javascript number. It has to make sense to increment, decrement or do other numerical operations on it. It's not to be used for strings or identifiers that just so happen to be numbers, e.g. credit card numbers. I'll admit this is slightly surprising to me but it does make a certain amount of sense.

The solution is to use `<input type=”text” inputmode=”numeric” pattern="[0-9]*">`.

[+] downerending|6 years ago|reply
One good reason for this is that for things like credit card numbers, a good interface will accept leading, trailing, or interior spaces. Sites that make me type in values in exactly their own weird format are an abomination.

Site A: Ah ah ah! You put a slash in your date! No soup for you!

Site B: Ah ah ah! You didn't put a slash in your date! No soup for you!

[+] pwdisswordfish2|6 years ago|reply
To put it more succinctly and without unnecessarily referring to JavaScript semantics, type="number" is for quantities, not mere strings of digits.

It's an unfortunate accident of the English language that both are commonly called ‘numbers’. We might not have had this confusion if some other language were the lingua franca of computing.

[+] dylan-m|6 years ago|reply
That's a good rule of thumb there :) More pedantically, credit card numbers _aren't_ numbers in the first place. They are identifiers that happen to use numerical digits. Same as phone numbers. Treating them as numbers at any point in a system is an error. My dream is this detail of the HTML spec forces people to rethink their schema design while they're at it.
[+] VBprogrammer|6 years ago|reply
I've come across this problem a number of times. The same applies in, for example, passing IDs across in JSON where I use strings if at all possible.

Even money amount are typically challenging to treat as numeric as often that drops them into a float when you shouldn't be processing money amounts as floats.

[+] robocat|6 years ago|reply
inputmode=”numeric” and inputmode=”decimal” have different quirks between Android and iOS. inputmode also acts differently on iPad and iPhone, and the keyboard shown varies from that for pattern=, and support for inputmode is missing from iOS11 (or iOS12?). Tread carefully!

Note that type="number" is particularly horrible on iOS because it allows typing non-numeric values and then input.value just returns zero. Instead you must check input.checkValidity(), and perhaps use the CSS :invalid pseudo-selector to show the user that their entry is not valid. You cannot read the actual invalid value AFAIK on iOS (although you could simulate it by looking at key events, if you ignore selection and cut/paste).

Data entry with HTML is one area where you really want a native app, and you can get severely burnt trying to use a WebView. I have wasted months dealing with a variety of quirks over the years trying to make time entry friendly in HTML: all solutions have terrible compromises, and different browsers act quite differently (and can have nasty bugs).

[+] gbersac|6 years ago|reply
I didn't knew you had an inputmode and pattern tag on the html input balise
[+] neves|6 years ago|reply
The main issue is that the numeric key pad, with larger buttons, are a lot easier to type (as predicted by Fitt's Law).

We must allow they to automatically use this keypad without the confusing behavior of the <input type=number>

[+] signalsmith|6 years ago|reply
This is off-topic, but I really like the current GOV.UK (several years old now). I don't really have opinions on the visual stuff, but I find it really pleasant to use.

Filing my self-assessment tax return (only required because I run a side-business) is a fantastically straightforward experience. Step-by-step information entry, pre-filled with what they already know (e.g. main employer's salary), then they give you a number at the end which you pay by card.

Having done the paper version exactly once before moving over to doing them online, I feel grateful every time I see that distinctive custom font.

[+] mattmanser|6 years ago|reply
Fantastically straight forward? I strongly disagree. I've done the SA many times, and trying to find out your balance or payments list or anything useful is now a kafka-esque nightmare. Last time I knew they must owe me money but they didn't say at the end, and it took me about 15 minutes to find out how much, with no indication of when it would arrive. At the end of the SA they even had some sort of message saying make sure you pay what you owe, which turned out to be nothing. This is all complicated because you pay on account, paying the next year's tax 15 months before you submit your return (they guess your next tax bill based on the previous one, as you don't submit the return for 9 months after the end of the tax year, so you don't get in too much credit).

The new SA process is no different from the old one, with minor cosmetic enhancements, but they've made it almost impossible to get to the old account sections.

Notice how there's no login button. On a website that relies on logging in. Now search for "self assessment login" or "self assessment account" or "self-assessment balance".

See any login button? See anything resembling a login? last year you could still get to the old account screen after some hunting, but that's gone now. The new account screen is a mass of text with links sprinkled through out, where the old one was a compact menu.

Plus, when you finally do find your accounts, you can only see one year at a time, have to use a drop down to change year, the amounts you owed are on one page, they amounts you paid are on another, some of these figures are still provisional, and nothing adds up.

As for submitting your company accounts, what a joke that used to be when they re-did it. I knew exactly what type of account I needed to submit. But to get to that form, I think they had a labyrinth of 16 web pages, each just one question per page, that you had to answer while they unhelpfully tried to pick the form you needed for you. Get the wrong form? No way to go back to see what answer you got wrong, no way to fix it, you just had to start again. It meant I had to go through it 3 or 4 times before I finally got the right form.

Before they "renovated" it, you just picked the form you needed.

They even did a whole blog post about how great the one page per question concept was, which turned out to be utterly bullshit.

I've lost all faith in the gov.uk team, I feel they're trying too hard to be cool and "innovative". They have thrown out convention, and are often making poor UIs and user journeys because of it.

[+] vitaliyf|6 years ago|reply
Similarly, here is your reminder than US Zip Codes aren't numbers, because many of us here in the Northeast have them start with a zero (or even two). So don't store them as integers, because Boston is 02108, not 2108.

See https://en.wikipedia.org/wiki/List_of_ZIP_Code_prefixes

[+] drstewart|6 years ago|reply
My general rule is if you can't add two values together then they shouldn't be represented as number types.
[+] pwdisswordfish2|6 years ago|reply
Some are yet to get the memo. Not so long ago, I've seen a TypeScript course that demonstrated union types with an example of representing zip codes as either strings or numbers…
[+] alexrage|6 years ago|reply
It's good to see UX design problems analyzed from a technical perspective. Designers working on the web should be proficient at understanding the medium on which they work, and look beyond generating static images to toss over the wall for implementation.
[+] shakna|6 years ago|reply
> However the inputmode attribute is now supported by all the mobile browsers we test in.

This isn't extensive, which might be a tad misleading if you don't double check. They test on Chrome & Samsung for Android, and iOS is only the one engine.

And those three browsers seem to be the only mobile browsers that have implemented it. (Well, Opera Mobile as well). [0]

Desktop support is also extremely spotty.

This seems like it might be leaping the gun on expecting this standard to pick up the slack.

Whilst they might feel the support is there for their particular audience after 2019, I wouldn't, and would suggest that you need to check your particular audience closely before following this advice for your own site. (Which is fairly generic advice, but appropriate.)

[0] https://caniuse.com/#feat=input-inputmode

[+] joelanman|6 years ago|reply
The article covers quite a few issues with type=number, including some pretty bad accessibility ones. On balance I think even if inputmode doesn't have 100% support, those users will simply get a normal keyboard, which isn't so bad. Disclaimer - I work on the team.
[+] signalsmith|6 years ago|reply
In this case, the fallback is still a plain-text field, into which the user should enter numbers. Perfectly usable, but without the keyboard hint, so it seems like a graceful fallback to me.
[+] globular-toast|6 years ago|reply
Using "numeric" types for strings that look like base 10 numbers is an incredibly common mistake. It's one of those mistakes that works 99% of the time, which means it can become deeply embedded in architectures. We've recently seen this problem when a database for the first time for a non-numeric system in its ids and downstream systems that converted that to an integer started to fail.

My rule of thumb is that if it doesn't make sense to do arithmetic on it then it's not a number, it's probably a string.

[+] reggieband|6 years ago|reply
> We've recently seen this problem when a database for the first time for a non-numeric system in its ids and downstream systems that converted that to an integer started to fail.

I can add another anecdote to that list. In my case it was some code in a consuming system that expected u16 sized int which broke when the producing system increased to 32 bit sized int. I mean, no code change just the auto increment on the database finally exhausted 16 bits.

Tangentially, this is why my first thought when designing a new system is to use uuid/guid stored as a string in hyphenated hexadecimal. It prevents any downstream consumer from even attempting to store it as an int. I'm now wary of things that look like int but aren't actually integers since people will often mistakenly treat them as such.

[+] markmark|6 years ago|reply
They were using it to get a numeric entry pad on mobile devices because users preferred that. They knew the types weren't "numbers". Now that inputmode=”numeric” has better browser support they recommend that.
[+] maxcbc|6 years ago|reply
This is the sort of thing I love about the accessible tech team at gds. They learn something, then they share it in such an accessible way.
[+] gatvol|6 years ago|reply
Quite strange that propriety systems like dragon are mentioned as motivation, surely they should fix the product or standardise.
[+] leokennis|6 years ago|reply
I guess that, as a government, they are required to cater for people with accessibility issues (in this case: people who cannot type but need to dictate to enter text).

If you then cannot support the most popular dictating application, that’s not a good look.

[+] rini17|6 years ago|reply
This is another reminder that floating point numbers are just a hack that should never be used by default. We have enough CPU, memory and bandwidth that we are able to transmit/store exact representation of numeric user input, and convert it to float only when necessary, as designed by programmer.
[+] ivanbakel|6 years ago|reply
Indeed. Just like 32-bit integers, having fixed size floats as the default representation of numbers with a decimal component is a bad holdover from days of limited hardware.

Let programmers use floats when they have the performance analysis to justify it. Before then, it's just another kind of premature optimisation - and high level languages should be avoiding it.

[+] rocqua|6 years ago|reply
It would be cool if more languages had support for fixed-point fractional numbers. Rolling your own requires re-implementing display and multiplication code, which is a decent reason for people to just use floats instead.
[+] TazeTSchnitzel|6 years ago|reply
<input type=number> for things that are like telephone numbers and not like quantities is such a common mistake. It can be hilarious when, for example, a login form uses such a field for a Swedish personal identity number. I just need to click the up arrow ~1.996×10¹¹ times!
[+] OisinMoran|6 years ago|reply
Really interesting article, and as with everyone else I also really admire their commitment to accessible design.

One interesting this I noticed in this piece was the text (not quoted for reasons that will soon become clear):

Using <input type=”text” inputmode=”numeric” pattern="[0-9]*"> allows for a degree of separation between how the user enters data (“input mode”), what the browser expects the user input to contain (type equals number), and potentially how it tries to validate it.

Which has incorrectly used closing quotes and correctly used straight quotes in the same code section, and then proper opening and closing quotes in the text section. I wonder how that happened.

[+] mirekrusin|6 years ago|reply
Gov UK has some great, Jakob Nielsen style UI. It’s fantastic to use, love it.
[+] nimish|6 years ago|reply
Javascript not having proper integers strikes again! Kind of surprised they hadn't run into more issues parsing string-ids-with-numerals into numbers.
[+] notriddle|6 years ago|reply
If JavaScript used 32-bit integers, then it would've just rolled over. Not much of an improvement.
[+] Fej|6 years ago|reply
Does anyone know what's going on with the Firefox implementation of inputmode, especially for Android? There isn't much on Bugzilla about it.
[+] calibas|6 years ago|reply
FYI, there's a few features available with the number input type that don't work with this method. Things like min, max and step attributes.
[+] _v7gu|6 years ago|reply
I'm just being cheeky, but you can abuse the pattern field to enforce minimums ans maximums
[+] eat_veggies|6 years ago|reply
min, max, and step don't make sense for things like account numbers or credit cards!
[+] BurningFrog|6 years ago|reply
This number type is fine. It serves a purpose.

The real problem is that there is no type for other "numeric" cases.

[+] ArchReaper|6 years ago|reply
EDIT: removed my inaccurate comment, misread article
[+] calibas|6 years ago|reply
How is the "tel" type a solution? According to the standard (https://html.spec.whatwg.org/multipage/input.html#telephone-...), it accepts every character except line feeds and carriage returns.

Without any pattern specified, the code you posted will accept emojis as input, it's not a good choice for a numeric only field. It's also intended for phone numbers...

[+] throwaway-q2233|6 years ago|reply
Better option is graceful degradation, just Target those specific problematic UAs for the other input type.
[+] shakna|6 years ago|reply
As with most accessibility problems... Checking my User Agent won't tell you how I'm interacting with the site.

How do you detect I'm using NVDA? It'll still look like Firefox. Or Chrome if I'm bypassing a broken UA detection.

Nowhere will you see NVDA, even though it is the problem.

[+] inanutshellus|6 years ago|reply
Unless I'm missing something, the graceful degradation is the `pattern="[0-9]"`. Certainly `input type="text"` is about as "degradation friendly" as you can get in HTML land...
[+] klingonopera|6 years ago|reply
I'm no web-dev, but shouldn't these things be sanitized server-side? In which case, except for the mobile keypad issue, all these problems would solve themselves?

And shouldn't they be doing this anyway?

[+] onion2k|6 years ago|reply
The point is that giving the user a number input is a bad user experience. For example, users don't need or want up and down spin buttons to enter a phone number. That's long before it gets to a server.
[+] thawaway1837|6 years ago|reply
These recommendations are irrespective of server side sanitisation.

Server side sanitisation doesn’t address any of the accessibility concerns. Server side sanitisation doesn’t address the silent dropping of characters concern. Server side sanitisation doesn’t address the incrementing/decrementing the value accidentally concern.

That’s because the issues being discussed here are about creating a good UI that minimizes errors, and has little to do with sanitisation.

[+] simion314|6 years ago|reply
You always should validate server side but this is to make it easy to use and accessible for users, PayPal has a custom input type that looks fancy but for example the Delete key is not working for it(no idea if is accessible or if you can type in it via speech)
[+] jkrems|6 years ago|reply
What makes you think they don't? But they still want good UX for entering the data.