alphagov / govuk-frontend

GOV.UK Frontend contains the code you need to start building a user interface for government platforms and services.
https://frontend.design-system.service.gov.uk/
MIT License
1.14k stars 319 forks source link

Investigate alternative to [type=number] for the date input component #1449

Closed NickColley closed 4 years ago

NickColley commented 5 years ago

We are aware of two issues with assistive technologies and their compatibility with [type=number]

We should investigate an alternative to this as we're aware of general issues with [type=number].

@hannalaakso has done a lot of investigation into this.

hannalaakso commented 5 years ago

If collecting dates as numbers, one problem with type="number" is that it has native input validation in Chrome (desktop and Android) which prevents the typing of non-numeric values. This is not a bug but an implementation of the HTML spec. Unfortunately the user experience is poor when it comes to handling errors. We recommend the use of clear error messages, whereas there is no information given to user about what they’ve done wrong if they attempt to type the month as a number, for example.

type="number" also allows the user to increment numbers by pressing the up/down arrows. This could improve usability for some users (as long as the number should be incrementable - dates generally are) but also introduces the risk of some users accidentally incrementing a number using the arrow keys when trying to navigate a form. The incrementing behaviour can be disabled using Javascript but we prefer to avoid scripting solutions if possible.

There are other issues with type="number" that concern long numeric values being validated by browsers and making sure that users can enter "-" and "," signs; but these aren’t a concern for dates.

Alternative solution (we should test this across the board) is to use inputmode="numeric" combined with pattern:

<input type="text" pattern="[0-9]*" id="sometext" name="sometext" inputmode="numeric">

There is also type="tel" which has no browser validation, and brings up a numeric keypad on all mobile devices (the input should set autocomplete=off to stop the browser trying to complete it from the user’s address book). It's often used by payment providers to collect credit card numbers. However on Android devices the keyboard includes additional buttons for "Pause" and "Wait" which could be confusing for some users. Additionally, there is the (admittedly quite slim) possibility that browser vendors might in the future add validation to type="tel", for which reason if it was used on a service, there should be a team available to monitor the behaviour.

NickColley commented 5 years ago

Just a note on the pattern attribute suggested, if someone has HTML5 validation enabled (something we do not recommend), it will show a message and stop the form from being submitted:

Screen Shot 2019-06-18 at 16 51 28
36degrees commented 5 years ago

We are already using the pattern attribute for the date input so that wouldn't be a change?

Possibly another reason to move away from it though.

36degrees commented 5 years ago

To summarise what we know so far:

At the minute for the date input component the individual inputs look like this:

<input […] type="number" pattern="[0-9]*">

We set the input type to type="number" so that Android browsers display a numeric keypad keyboard when the input is focussed.

iOS uses the full alphanumeric keyboard for type="number", so we add pattern="[0-9]*" which triggers the numeric keypad there too. This is technically invalid HTML, as the pattern attribute only applies to inputs of type text, search, url, tel and email, but is not known to cause any real-world issues.

However, there are a number of known issues with inputs of type="number":

(Bugs have been filed where appropriate)

In testing, using <input […] type="text" inputmode="numeric" pattern="[0-9]*"> mitigates these issues, with some minor drawbacks:

We think that <input […] type="text" inputmode="numeric" pattern="[0-9]*"> is semantically correct and provides a better experience and so we should:

36degrees commented 5 years ago

Once we've done the above, we can also close https://github.com/alphagov/govuk-design-system/issues/782

36degrees commented 4 years ago
  • In iOS 12.2 and above, the numeric keypad with punctuation is displayed instead of the numeric keypad, but this looks like it has been changed in Webkit so this should hopefully change in a future iOS release (versions prior to 12.2 do not support inputmode, thus fallback to the pattern attribute, and continue to show the full numeric keypad.)

Just to confirm that iOS 13 now shows the numeric keypad.

kellylee-gds commented 4 years ago

@36degrees close this card and create new one with what we want to do

36degrees commented 4 years ago

Closing this as I believe we've finished the investigation and now have cards representing these actions:

tempertemper commented 4 years ago

A bit late to this, but I was wondering why inputmode="numeric" was used instead of inputmode="decimal". It's the same keyboard either way on Android, but on iOS numeric uses the same keyboard as type="number" (with the numbers in a row and lots of punctuation options), but if we're only asking for a number, the number-pad style (a 3 x 4 grid with numbers 0 to 9) feels more appropriate. The touch targets are also much larger, which can only be a good thing.

hannalaakso commented 4 years ago

Thanks for your comment @tempertemper. See https://github.com/alphagov/govuk-frontend/issues/1449#issuecomment-539906569 - iOS 12.2, 12.3 and 12.4 display the keypad with punctuation that you describe but this was fixed in iOS 13 which displays the large numbered keypad with numeric. Are you on one of the above mentioned versions of iOS?

tempertemper commented 4 years ago

@hannalaakso I totally missed that one – I had been testing with iOS 12 so saw the other keyboard. Numeric is perfect 😄 I've attached a couple of screenshots (taken from @adamliptrot-oc's excellent test page) for posterity: the difference is that decimal has a decimal point and numeric doesn't. So numeric is the right choice as the . it's always going to be a whole number. Thanks for keeping me right 🙂

Decimal: decimal

Numeric: numeric

hannalaakso commented 4 years ago

@tempertemper No worries at all, glad we got it figured out 🙂