Skip to main content

https://technology.blog.gov.uk/2020/02/24/why-the-gov-uk-design-system-team-changed-the-input-type-for-numbers/

Why the GOV.UK Design System team changed the input type for numbers

Posted by: , Posted on: - Categories: Open Standards, Tools

A screenshot of the new number input guidance

To provide users with a good service, government organisations usually need to collect data. Lots of data. The GOV.UK Design System team publishes patterns and components that let users enter their data in an easy and accessible way. The last thing we want to do is create barriers to users completing a task and force them to find an alternative method of using the service, such as phoning a helpline. 

Numbers are one of the most commonly asked for pieces of data, typically used in dates. We know from user research that some users prefer the large buttoned number keyboard (resembling a telephone keypad) for entering numbers on mobile. Until now, the GOV.UK Design System date input component used the HTML element <input type="number"> to provide this number keypad when a user enters dates.

A large buttoned keypad used on Android devices
Large buttoned, easy to use number keypad on Android

However, we recently moved away from <input type="number"> to <input type="text" inputmode="numeric" pattern="[0-9]*"> and published new guidance on how to ask users for numbers.

Why type=number is problematic

Although we have user research from 2017 that didn’t flag any major issues with <input type="number">, we identified many usability problems with this input type.

1. Accessibility

We found that <input type="number"> :

2. Incrementable numbers

It's reasonable to assume that <input type="number"> can be used for collecting any numeric data: it contains the word “number”, after all. However, a note in the HTML specification states that <input type=”number”> is “not appropriate for input that happens to only consist of numbers but isn't strictly speaking a number”.

This means that <input type="number"> can only be used for incrementable numbers, such as dates or the number of people in a household. Using <input type="number"> for collecting numbers that are not incrementable can cause problems with browsers validating them in that way.

For example, browsers attempt to round large numbers when incrementing or decrementing (pressing up or down key), and in the case of very large numbers they are converted to exponential notation.

Chrome 79.0: type=number displays large numbers in exponential format if user presses the up or down arrows on their keyboard

Once the number is parsed by the browser as an exponent, as shown above, and possibly by mistake, the action cannot be reversed by the user. This could confuse users. 

If users access your site using older versions of Safari, <input type="number"> can also be problematic when collecting values of 16 or more digits. In Safari 6, the browser rounds the number when a user leaves the field, so no mistake with up or down keys is required.

Safari 6 rounds the last digit on blur

Safari 5.1 attempts to make values with at least 16 digits more readable by inserting commas.

Safari 5.1 attempting a more human readable number on blur

3. Letters 

The HTML spec states that when using <input type="number">, “user agents must not allow the user to set the value to a non-empty string that is not a valid floating-point number”. The web and Android versions of Chrome implement this by silently discarding all letter input except the letter ‘e’.

This means users are not given feedback on what type of characters <input type="number"> accepts, and assistive technologies don’t alert the user that their input has been silently discarded.

4. Scrolling 

Users can accidentally increase or decrease the number using the scroll wheel on the mouse or the scroll gesture on their trackpad. This feature can be useful when collecting countable data but bad if entering data such as passport numbers.

The solution

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. 

Prior to 2019 there wasn’t enough browser support, especially on mobile devices, for us to feel confident in rolling this out instead of using <input type="number">. However the inputmode attribute is now supported by all the mobile browsers we test in.

We still include the pattern attribute for backwards compatibility with older iOS devices.

We’ve now updated the date input component and the rest of the relevant patterns.

We’ve also published some guidance to help users to understand how to collect numbers in HTML forms.

Finally, we’ve proposed a change to the HTML spec guidance to cross reference inputmode when using <input type="text"> with content that is only numbers

You can take a look at the GOV.UK Design System backlog to see what else we’re working on.

If you're interested in learning more about changes like these, listen to the February episode of the GDS podcast.

Sharing and comments

Share this page

28 comments

  1. Comment by Kim McGreal posted on

    This is really interesting, especially when looking at it from an accessibility point of view. Thanks for the explanation 🙂

  2. Comment by Colin Cummins posted on

    This seemed well laid out, simple to read and understand (from my non-technical point of view), and quite crucial from an accessibility view point.

  3. Comment by Thomas Finney posted on

    That's actually really clever. The sole reason I would prefer to use `type="number"` would be for the number pad on mobile devices. The `inputmode` is super neat.

  4. Comment by Robi Harid posted on

    Great stuff. GDS continues to deliver!

  5. Comment by Brandon Heyer posted on

    I couldn't not comment, there are so many things factually wrong with this and the decisions made appear to be rash an ill-informed.

    1. The provided links reference Dragon 13, that is around 6 years old. Dragon 15 is currently out. A lot has changed since 2014.

    2. A credit card is NOT a number it is a string of digits/numerals: "an arithmetical value, expressed by a word, symbol, or figure, representing a particular quantity and used in counting and making calculations and for showing order in a series or for identification." Credit card numbers / reference numbers are non-quantifiable.

    3. This is confusing, sure, but should we not allow numbers greater than 10 because some people may not know how to count that high? Or binary numbers, because people don't understand it? 1eee10 is a valid number and is roughly 200.85. Furthermore, I tried your suggested version in chrome:
    <input type="text" inputmode=”numeric” pattern="[0-9]*> It provides no feedback when I enter non-numeric values.

    4. Again, an invalid argument because passport numbers are NOT real numbers.

    Closing: `inputmode` is actually quite poorly supported, no support from IE or Chrome. I'd also like to know whether or not `inputmode` and `pattern` are provided any support with Dragon/NVDA

    • Replies to Brandon Heyer>

      Comment by Hanna Laakso posted on

      Hi Brandon,

      Thanks for your comment.

      1. We’ve also replicated the problem in Dragon 15: see comment further down that page.
      This issue in Dragon has been around for a long time unfortunately, hence the comments going back to Dragon 13.
      (Generally speaking, buying new versions of assistive technology can be expensive so we can't expect users to be on the latest version.)

      2. The point made in the blog post is that teams implementing forms might not be clear on differences between types of numeric data to the level of detail that you quote, unless they read the note in the HTML specification that advises against using `<input type="number">` for non-incrementable numbers and possibly do some of their own investigation. Since the HTML input types contain no other obvious candidate for collecting credit card numbers it would not be unreasonable to choose `<input type=“number”>`, especially as it conveniently brings up the large buttoned number keypad on mobile devices.
       
      3. If `<input type=“number”>` is used for collecting non-incrementable data which gets incremented by mistake then the service could fail for the user. Or as the HTML specification says in this context: “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.”
      Regarding your comment about not getting browser feedback with `inputmode`: the problem with `<input type=“number”>` is that it discards user input without notifying the user and this could create barriers to users completing their task. With `inputmode` the user can type in their answer in a format that suits them and submit the form: if the server detects a problem with their answer it refreshes the page with an accessible error message telling the user what the problem is. In this way the team retains control of how users find out about errors and can ensure that users can recover from them. Relying on native browser validation might not be a good idea as it can be implemented inconsistently by different browser vendors: `<input type=“number”>` discarding user input only in Chrome is a good example of this.
      This is a complex topic but our team are just about to publish some related guidance - I’ll add a link to it here when it’s published as it covers the topic of helping users recover from errors in more detail.  

      4. Same as 2. Teams creating forms might not be aware of the HTML specification and choose to use `<input type=“number”>` as out the HTML input types it seems the most suitable.

      `inputmode` is supported on all the mobile browsers we test in which means that we can display the large buttoned number keypad for users. `inputmode` is supported by Chrome. IE doesn’t have a mobile browser.

      I hope this helps.

  6. Comment by Owen Miller posted on

    This is fantastic. I'll have to get it implemented at my startup

  7. Comment by Heather Herbert posted on

    Additionally, when entering some "numbers" such as credit card information you may want to allow the user to add a space i.e. 4544 4444 4444... This doesn't work with type=number

  8. Comment by Anthony Owide posted on

    This has blown my tiny mind! Thanks for sharing your research 🙂

  9. Comment by Salomao Rodrigues posted on

    Could the author of this blog post explain the points outlined by @Brandon Heyer?

    Looking at caniuse.com, inputmode doesn't seem to be well supported at all...

    • Replies to Salomao Rodrigues>

      Comment by Hanna Laakso posted on

      Hi Salomao,

      Thanks for your comment.

      `inputmode` brings up the large buttoned number keypad for users on mobile. All the mobile browsers that we test in now support `inputmode`: that’s Safari and Chrome on iOS, and Chrome and Samsung Internet on Android.

      I hope this helps.

      • Replies to Hanna Laakso>

        Comment by Nicholas Johnson posted on

        And mobile is all we really care about here. Inputmode would have be effect on a desktop device.

  10. Comment by isral Duke posted on

    This is fascinating. i didn’t even know about the pattern and inputmode attributes. i’ll be implementing this in my own work. thank you for writing this.

  11. Comment by Rob Schlüter posted on

    "Until now, the GOV.UK Design System date input component used the HTML element <input type=”number”> to provide this number keypad when a user enters dates."

    Why use input type 'number' or 'text' when a specific date type exists? That informs the browser the exact intent of the field so it can provide a matching user interface.

    By using number of text that intent is missing and developers have to add extra labels, upper/lower limts or regexes as described.

  12. Comment by Quentin Bellanger posted on

    I would add that browsers handle and parse decimal separators (, or .) differently depending on user's language settings.

    Thanks for the explanation, great post, as usual. ?

  13. Comment by Remi Shergold posted on

    This was a really interesting read. We use gov.uk design advice extensively in our UX team.

    We're a blue chip financial company with public facing apps that often require high value currency inputs. Say we ask a user to enter the value of their house, they may enter "300000" "300,000" "300,000.00" "300.000,00"(German et al) the list goes on.

    It's hotly debated if we should use the number input. The main arguments for is the keypad on mobile and that it helps users with screen readers.

    Is there any official advice on currency number inputs? It's a little surprising there isn't a dedicated component for this in the gov.uk design system.

    • Replies to Remi Shergold>

      Comment by Alistair MacDonald posted on

      Is it possible to use a opacity=0.0 number input to trigger the keypad, but have each digit/symbol entered pass through to a handler that processes the result and places it in a text box?

  14. Comment by concernedCitizen posted on

    You have to ask yourself if the government is focusing on the wrong areas?
    Yes a certain level of accessibility is required for such far reaching services.
    However, one has to way up the value when considering the dire state of other government funded and/or supported technologies.
    For example, doctor's surgeries have recently stopped taking repeat prescription orders over the phone. Patients are now required to use either; a website, an app or order in person. Obviously, ordering in person is only feasible for a small percentage of patients.
    This leaves a variety of patients left to use the worst app I've seen in a long time. It's called "SystemOnline" and it's basically unusable unless you're less than 40 years old (sorry oldies.)

    Now I'd rather see government money put towards the creation and maintenance of essential technology's, rather than making services better for the less than 1%. Who most likely have £1000's worth of aids such as; people, glasses, hearing aids, voice input etc etc.

    My point is, the less than 1% have several alternatives, already catered for by the government. The huge portion of over 40's that are now super frustrated with or not even getting repeat prescriptions is a much larger issue. Which could be solved by the same people who are essentially hacking together a super small improvement for screen readers; which will most likely only stay relevant for 1 or 2 years.

    • Replies to concernedCitizen>

      Comment by devops posted on

      Check the article again. The implications of the issues with input number type are fairly wide-reaching when it concerns numerical accuracy, not just screen readers. This article is like pointing out an issue with a certain engine component and your response is like asking the same team to fix a car.

  15. Comment by gandharv garg posted on

    Great stuff!! Killing it gov.uk

  16. Comment by Derrick posted on

    This is really helpful

  17. Comment by Andrew posted on

    There is another reason not to use type=“number”, and that is, unless the number is regarded as valid by the browser then change/input events won’t send out the actual value that the user input. They will instead send out a blank string. This means you cannot run a custom validation library on the user input, and so you are at risk of losing users’ input data because you can’t capture what they have typed.

  18. Comment by zakius posted on

    since when "only Blink supports it" is good enough?

  19. Comment by Chris Moore MBE posted on

    Fantastic to finally see Android support this pattern. To get around this in the past we had to use the 'tel' input type to ensure a numeric keypad was displayed on Chrome web browses.