Menu Search
Jump to the content X X
Smashing Conf Barcelona 2016

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. upcoming SmashingConf Barcelona, dedicated to smart front-end techniques and design patterns.

Form Inputs: The Browser Support Issue You Didn’t Know You Had

The lowly form input. It’s been a part of HTML for as long as HTML has had a formal specification1; but before HTML5, developers were hamstrung by its limited types and attributes. As the use of smartphones and their on-screen keyboards has flourished, however, inputs have taken on a new and incredibly important role — but they’re also riddled with browser and device inconsistencies.

The eight original input types were brilliant in their simplicity. (Well, OK, maybe <input type="image"> hasn’t aged very well.)

Think about it: By inserting a single element in your markup, you can tell any web browser to render an interaction control, and you can completely modify that interaction – from a text field to a checkbox to a radio button – by simply changing a keyword. Now imagine a world where creating these interactions means also creating custom interaction controls, and you begin to realize how taken for granted inputs really are.

Unfortunately, even Tim Berners-Lee and Co. couldn’t have anticipated the strain that mobile devices and interaction-hungry web applications would place on these original concepts for user input.

That’s what the HTML 5.0 specification was intended to solve, by expanding the concept of the text input to allow for specific data types, such as numbers and email addresses, as well as rich interactions, such as task-specific on-screen keyboards and date- and color-pickers. Most were designed with graceful degradation at their core, adding enhancements to supported browsers while falling back nicely to basic text inputs in older ones.

Or at least that was the intention. In the real world, many of these new inputs and attributes — even seemingly innocuous types like <input type="number"> — don’t always behave as you might expect.

Identifying The Problem Link

While not as fierce as battles of yore, input types are the cause of a new small-scale browser war. Despite the existence of standards, browser and device manufacturers have cherry-picked input feature support and taken different approaches to implementing these enhanced interactions.

Take date. Using <input type="date"> is a godsend to any front-end developer who has ever had to add a JavaScript-based date-picker to a website… or at least it would be if all browsers supported it. Desktop versions of Chrome and most mobile browsers display a native date-picker:

Native date-pickers shown when using the date input type in Chrome for iOS and Mac2
Native date-pickers shown when using the date input type in Chrome for iOS and Mac (View large version3)

However, as of Firefox 36 and Internet Explorer (IE) 11, that same input type defaults to a plain ol’ text field, forcing developers to use polyfills4 or to continue building JavaScript-based date-picker solutions instead.

The date input type defaults to a plain text field in Firefox 36.5
The date input type defaults to a plain text field in Firefox 36. (View large version6)

The lack of date input support in Firefox seems at odds with the vendor’s overall support for these more visually and functionally advanced input types. For example, the range input type (<input type="range">), which emerged from the same crop of proposed features as date, has been supported since Firefox 23 and IE 107.

Firefox has supported the range input type since version 23.8
Firefox has supported the range input type since version 23. (View large version9)

In fact, IE’s implementation, although not the most visually attractive, has some added utility, allowing you to see incremental divisions within the range, as well as its current numeric value on mouse drag.

Internet Explorer 10+’s implementation of the range input type shows incremental divisions and its current numeric value on mouse drag.10
IE 10+’s implementation of the range input type shows incremental divisions and its current numeric value on mouse drag. (View large version11)

We’re used to dealing with mixed browser support for emerging features. But when it comes to inputs, there’s a bigger problem: Even when an input feature is supported, it’s not always implemented in the same way across browsers or mobile platforms. Developers now have to take all of the following aspects of an input into account:

  • type
    Does the input’s type reflect the data that’s being entered (for semantic and validation purposes), and does it also trigger the correct keyboard in Android?
  • validation pattern
    Does your pattern allow for the correct characters to be entered, and does it also trigger the correct keyboard in iOS?
  • step attribute
    In certain browsers, do the small up and down arrows associated with a number input allow the user to increment or decrement their input in the correct steps?
  • required attribute
    If an input is required, do its type, pattern and step values all contribute to the format you’re expecting, and is this true across all browsers on mobile and desktop?

Imagine a situation in which you need to add a required input field for currency, and you want to display the best possible keyboard experience across all devices. “Simple,” you think, adding <input type="number" required> to your form. This works great for Android:

An appropriate keyboard is displayed to Android users for the numberinput type.12
An appropriate keyboard is displayed to Android users for the number input type. (View large version13)

In iOS, your keyboard would be improved (the top row will show numbers):

In iOS, the keyboard displayed in response to the number input type contains the number keys.14
In iOS, the keyboard displayed in response to the number input type contains the number keys. (View large version15)

But that’s still not the fancy 10-key keyboard Android gives you. To achieve something similar in iOS, you need to set a pattern attribute with a value of [0-9]*:

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

In iOS, this combination gives us this:

Setting the pattern attribute to [0-9]* prompts iOS to display a number pad.16
Setting the pattern attribute to [0-9]* prompts iOS to display a number pad. (View large version17)

I believe this implementation to be a fundamentally shortsighted decision on Apple’s part. Not only does it ignore the input’s type altogether, it’s also based on a pattern that’s hardcoded into the OS, which means that if you alter that pattern in any way, you will lose the keyboard enhancement entirely in iOS.

In our currency example, this creates a problem, but not where you might expect. A required input with a number type and a pattern of [0-9]* will give us great results across mobile, but it’s easy to forget that these decisions also affect desktop browsers. On desktop, we can’t control the user’s keyboard, and if they enter a special character (such as a comma or dollar sign, which are both plausible for currency), both the type and the pattern will cause it to fail client-side validation. (In older versions of Chrome, decimals also cause validation errors, although adding step="any" solves this issue.) You can see the problem here:

Characters that don’t match the specified pattern will throw errors in desktop browsers, where keyboards cannot be controlled. (View large version19)

This leaves developers in a bit of a lurch. We can choose to enhance one mobile OS experience at the expense of the other, enhance both of our mobile experiences at the expense of desktop, or enhance our desktop experience at the expense of mobile. And none of these options would make our stakeholders very happy.

Zip It Up Link

Although currency is one of the most illustrative examples, almost any input that needs to allow for alphanumeric content with special characters can cause some of the heartburn that comes with using these new input types and patterns. This includes social security numbers, phone numbers or any number that could be entered in an unknown format, such as a bank account number. For this next example, let’s examine one that’s often overlooked: US ZIP codes.

Without giving them much thought, ZIP codes seem relatively simple: most people immediately think of them as a five-digit number. So, we can just use <input type="number">, right? Wrong, for two reasons.

The more obvious reason is the extended US ZIP code format (i.e. 12345-6789). Although it may be less common, allowing our users to enter it this way is still important. And we also need to keep non-US users in mind, because several countries (including Canada and the UK) use letters and other special symbols in their postal code formats. Semantically, ZIP codes aren’t numbers: They’re numerical codes — you’d never refer to a certain ’90s teen television drama as “Beverly Hills Ninety Thousand Two Hundred Ten.”

The second reason is a little subtler: some ZIP codes on the far east coast of the US begin with a zero.

If you’re validating these fields, special characters will immediately cause a validation issue, and in many browsers (including old versions of Chrome), so will that leading zero. That means not being able to use a number input type and, therefore, no enhanced keyboard for Android.

Android users may be out of luck, but can we still enhance for iOS? If you want to validate the field, the answer again is no, caused in large part by Apple’s decision to base its enhanced keyboard on a single hardcoded validation pattern. If we want to use <input type="text" pattern="[0-9]*"> (the hardcoded pattern that triggers iOS’s 10-key keypad), our users won’t be able to enter special characters or letters. Even if you disregard non-US users and use a pattern that allows for extended ZIP codes, such as <input type="text" pattern="(\d{5}([\-]\d{4})?)">, you’re still not going to get back that enhanced iOS experience that would benefit users.

These currency and postal code examples also don’t take into account support for other attributes that can be slapped on form inputs, such as autocapitalize, autocomplete and autocorrect. Autocapitalize and autocorrect are features created by Apple that work in iOS and Safari but aren’t officially part of the HTML specification and will fail W3C validation. Autocomplete, on the other hand, is part of the official specification, but as of version 34, Chrome ignores and overrides this attribute by default20 to support its built-in form autofill functionality.

It probably goes without saying, but also very little can be done to support users who install third-party keyboards on their devices. After all, if your user’s on-screen keyboard looks like two video-game joysticks or a rotary telephone21, then you will very likely be unable to reliably control how it responds to advanced input types and attributes.

Send In The Hacks Link

As with most standards issues, there are workarounds, and there are problems with the workarounds. The one I’ve seen advocated most frequently for dealing with numbers and currency is the use of <input type="tel">, which creates the closest thing we’ve got to a cross-platform 10-key keyboard solution:

Setting an input’s type to tel will display a 10-key keypad on both iOS and Android.22
Setting an input’s type to tel will display a 10-key keypad on both iOS and Android. (View large version23)

This does produce a 10-key keypad on Android and iOS, without enforcing a pattern on desktop. But as you can see by this keyboard’s secondary screen, it’s also clearly not a best practice:

Unfortunately, the tel input type’s secondary keyboard is telephone-specific.24
Unfortunately, the tel input type’s secondary keyboard is telephone-specific. (View large version25)

Do we really want to present users with a phone keypad that includes keys for “pause” and “wait” when they aren’t actually entering a phone number? And what happens to our websites if mobile platforms and browsers change the way telephone inputs are handled?

The second most common solution I’ve seen is to use JavaScript to strip special characters from inputs26 as our users enter content into them. This will get the job done, but it’s arguably not a good user experience. Users might be confused when the text they enter doesn’t appear on screen, or appears momentarily and then disappears.

Common Sense And Communication Are Key Link

Both of these solutions hark back to the days of using star and underscore CSS hacks27 to sidestep odd behaviors in old browsers (especially IE 6) — and we shouldn’t go there again. These hacks are a conscious decision to sidestep standards and best practices to complete the task at hand, without giving much thought to what will happen to our code base as browser support matures and feature implementations evolve.

Another solution may be on the horizon in the form of the WHATWG’s proposed inputmode attribute28. By using this attribute, developers could declare a specific state that hints at which input mechanism would be most helpful, with a predefined fallback state. For example, <input inputmode="tel"> would fall back to a numeric state if a device’s keyboard doesn’t support telephone input, and <input inputmode="numeric"> would display a number keyboard but also allow for negative numbers and a thousands separator. Unfortunately, support for this proposed attribute is still extremely limited29, and just like input types and patterns, we’ll have to wait and see if it’s implemented consistently across all browsers and devices.

For now, adhere to each input type’s intended purpose if you want to future-proof as much as possible. Assume that the rules for what triggers specific keyboards and behaviors on all platforms and browsers can — and will — change.

If you do use these newfangled input types and patterns, then test, test and test again, on as many devices as you can get your hands on. I created Input Type Sandbox30, a utility for trying out different combinations of types, patterns and attributes, for exactly this purpose.

Not shying away from discussing this up front with stakeholders is also important. It’s willful ignorance to think they’ve never used an enhanced keyboard on their mobile device and that they wouldn’t want the same experience on their own website. I can say from personal experience that if your website’s forms are lengthy, you’ll save hours of explanation and rework if stakeholders are made aware of the possibilities and limitations of form inputs from the beginning.

A Call To Action For Platforms And Browsers Link

The real issue here has nothing to do with the wonderful new abilities that HTML5 inputs give to us developers; the patchwork of support and implementation are the problem.

The only true solution is for all browser vendors and device manufacturers to operate from the same playbook. Specifically, we need to demand the following:

  1. Browser vendors need to support all standards-based input types as soon as possible. A powerful new feature on one platform isn’t truly powerful until it’s commonplace enough for us to confidently use in the real world.
  2. All mobile platforms should follow the same rules for what invokes a particular on-screen keyboard. Personally, I think Android has the right idea in using type and not the validation pattern, as iOS does. But what matters is not the method, but consistency.
  3. Client-side validation needs to work consistently across all browsers and platforms, and soon.

Tracking every browser vendor and device manufacturer’s plans for supporting this patchwork of types and patterns is tricky, although we can glean some information from their bug-tracking and support websites. For example, Microsoft says <input type="date"> will be supported31 in its upcoming Spartan browser. This leaves Firefox as the lone holdout, despite a Bugzilla ticket32 that’s been open since 2012. I can’t find any official comment on whether Mozilla plans to add support anytime soon.

I also wasn’t able to find any information on Apple’s plan to enhance or alter its keyboard inputs for iOS, although its “Text Programming Guide for iOS33” still recommends (inaccurately, I believe) using its notorious hardcoded <[0-9]*> pattern for ZIP codes.

In the near future, I expect most of these inconsistencies will be resolved, and we can once again start taking these glorious form inputs for granted all over again. But until that happens, let’s all agree to stick to the standards and best practices that have gotten us so far in the first place.

(og, al, ml, il)

Footnotes Link

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
SmashingConf Barcelona 2016

Hold on, Tiger! Thank you for reading the article. Did you know that we also publish printed books and run friendly conferences – crafted for pros like you? Like SmashingConf Barcelona, on October 25–26, with smart design patterns and front-end techniques.

↑ Back to top Tweet itShare on Facebook


Aaron is a UI engineer from Kansas City. In addition to his full-time role at DEG, he’s the co-creator of, a testing utility for onscreen keyboards, input types and validation patterns, and Yeo+Lab, a scaffolding tool for Pattern Lab. He¹s currently obsessed with front-end performance, workflow tools and build processes. Outside of work and freelance, Aaron is a cliché Kansas City BBQ snob and brews some really bad beer.

  1. 1

    Something that would aid in maximum support would be closing your goddamned tags properly!

    Although the standard now says it’s not ‘required’, many strict environments still like it, and it’s still syntactically correct. If you’re looking to avoid any surprises, asking your browser to guess where your tags close isn’t a great way to start.

    If you’re writing HTML and you’re not closing a tag, then it needs to self close, and you do that with a slash.

    • 2

      Sorry, this is a personally gripe of mine as I often use XSLT as a templating language, which enforces proper HTML syntax, which includes closing tags properly.

      The way I see it is that by omitting them you *could* (in limited situations) introduce an issue. By including them you lose absolutely nothing.

      So why not just include them?

      • 3

        I imagine most devs would tend to agree with you, especially as most IDE setups these days automatically close tags for you.

      • 4

        XSLT enforces XML standards.

        The only times HTML tags, as childless entities, will cause issues to your end user are when you’re either forcing an ancient doctype (4.01 strict, XHTML 1.0, or less useful), or when your context actually requires XML.

        If you’re forcing ancient doctypes, stop (also, this article is foundationally useless to you, at that point), if you’re writing views which are included in XML feeds, or in document types expecting XML or some extension thereof (Java/C# apps, using various page/form rendering frameworks, native views for mobile devices, et cetera), who’s going to guarantee that those image tags with type=”datetime” attributes are going to be handled consistently across each of your apps?

        Why would you force the CSS-styled HTML (no longer an extension of XML) to look like XSLT-styled XML, when the benefits of dragging and dropping them from one view to another are lost, and you’ve basically just saved yourself typing 7||8 characters.

        Not all code editors adhere to XML for HTML, either.
        Yes, most IDEs treat it that way, but then again, Eclipse still can’t deal with 100% of the syntax of ES5, properly, let alone ES6/7.

        Do we *really* want to force all devs to be complicit with Eclipse, for standards purposes, as far as front-end goes? Babel happily converts ES6 to ES3; eclipse would prefer you write ES3. Why not just skip the middle-man, and conform to what the productivity tool wants you to do?

  2. 5

    In putty pes.

  3. 6

    The lack of date support in FF/IE really gets me – especially because on mobiles there is very good native support.

    The other issue we have is most polyfills are absolute terrors on mobile – fiddly and difficult to use, when compared with native pickers.

    I end up using the date input type, but using JS to remove it for desktop browsers and load a JS picker instead. It’s just not good and I’ve yet to find a better solution.

  4. 7

    The problem can be even worst in Android devices. Manufacturers can modify the OS to include their own keyboards. So, if your input request the numeric keyboard, it sometimes don’t have commas and periods.

    I developed a web application for a company internal use and had all the problems in the article and the fact some users had an old Android subversion where Samsung changed the numeric keyboard to something unusable. I have to use a javascript hack to change the behavior of these inputs just in these devices.

  5. 8

    Martin Chaov

    May 5, 2015 4:13 pm

    I’ve had similar issues with field that needs to receive only numbers. Bottom line we’ve implemented our own keyboard with the symbols we need and a that looks and behaves line an input.

    The best part of it, is that it doesn’t affect the layout whenever you need to enter a number :)

    • 9

      Martin Chaov

      May 5, 2015 4:15 pm

      it seems HTML is stripped away and not encoded… I was saying that we have a HTML element that looks and behaves like and input.

  6. 10

    Great article! Answered all my questions on form inputs!

  7. 11

    Saint Jose

    May 6, 2015 5:58 am

    Great article , I think Browsers Cookies issue ..In history every time we clear it and also HTML EnCoded also. Thank you…

  8. 12

    Few things as depressing as an article that offers no actual solution except for browser developers to get their shit together, which is nothing new.

    • 13

      It’s not like you bashing this article gets anything done either!

  9. 14


    Great article!

    Minor note on the numeric keyboard and iOS.

    It’s actually great that it’s not the digits-only keyboard, because that one doesn’t have the `.` and `,` keys required to input decimal numbers.

  10. 15

    Very good article on the sad implementation state of that part of HTML5.

    BTW, number fields have another serious problem when it comes to internationalization. In an English form, thirtysix hundred will be written as “3,600.00”, in German and Italian it’s “3.600,00” and in French it’s “3 600,00”. AFAIK, there’s no way to deal with that in a way that’s even close to compatible in the current versions of major browsers. Some seem to follow the HTML lang attribute here, some don’t, and there are subtle differences between client validation and how the values are posted to the server. For an implementer, that’s practically useless.

  11. 16

    > Do we really want to present users with a phone keypad that includes keys for “pause” and “wait” when they aren’t actually entering a phone number?

    Of course, I’d do that — and I’d expect that as a potential client. “Phone numbers” are really not numbers, they are dialing command strings. Imagine you’re a client whose contact number is hosted behind some PBX which requires a 2-sec wait before dialing an extension number. Or a voice-mail number that accepts a message only after a signal. Or a system which requires entering a PIN code. Or a system with voice-menu. Or a ring-back system. Hell, there still exist some really old PBXes which require switching to pulse-dialing! How would you enter and save the number, keeping these dialing tips and allowing you to automate your calls? Hence, despite the fact the common “phone number” contains mostly digits, it is just a subset of the Hayes command set , and what you see on the extended keyboard is just some common sub-commands for the “ATD” command (which may include “P”, “T”, “W”, “R”, “@”, “,”, “;”, “!”, “L”), see

    Same note on the postal code: as you correctly mentioned, the fact many countries use digits in their postal codes doesn’t make it a number in mathematical sense. Input type=”number” is intended to input quantities. Zip code, like a phone number, is not a quantity at all, it is just a string of characters, and the keyboard for zip code input should allow to enter any character, not just digits. That’s why I’d expect to have a full keyboard, not the “enhanced” numeric one.

  12. 17

    Agree with Andrey when he says, “That’s why I’d expect to have a full keyboard, not the “enhanced” numeric one.” In fact, the first iPhone keyboard shown for number input is the most useful one and I’m sure I’m not the only person who wants to know how website developers could implement it for Android. It sure would save Android users from having to bring up their secondary keyboard without thinking their dialler had been hacked.

  13. 18

    great article! but what if you want an input type=password to use a numeric keypad? Do you use JS to show “*” for the input or is there another way?


↑ Back to top