Developing mobile-friendly forms

Goals when developing mobile-friendly forms

There are several goals when delivering mobile-friendly forms:

Forms should be easy to complete. Adjusting each form element’s size and layout is the primary technique for improving legibility and user manipulation. Usability will, however, also depend on your choice of form elements, the clarity of your form labels, and the efficacy of your form validation.


Example A shows a form that has been optimized for usability and legibility. Example B shows an un-optimized form.

Forms should be lightweight and compatible with target browsers. Being compatible doesn’t mean that they will be identical on all devices. They should, however, be functional and easy to use. They should also not be so complex that their rendering will cause unnecessary browser latency.

Forms should, where possible, take advantage of new technologies to enhance the experience on more advanced browsers. This is typically achieved through the addition of new HTML5 input types, some of which provide the user with advanced native behaviors such as date picker components and built-in form validation.


A date picker component on the iOS platform

Achieving these goals will often require a certain level of compromise. Mobile browsers are constantly improving, but support for the latest technologies still varies. You should be prepared for cases where the desired support is unavailable or poorly implemented. And while it can be tempting to develop your own user input components, you should always consider the value and maintenance burden these will involve.

HTML5 form attributes and input types are extensively discussed in this section despite the fact that they are not supported on many devices that meet the default Works experience criteria, discussed in Experience categories and enhancements in "Mobilizing the Mileage Stats App." These aspects of the HTML5 specification have, however, been designed to degrade gracefully, so they can be implemented on most browsers with minimal risk. To ensure compatibility, any implemented feature should, of course, be tested on target devices.

Form element implementation in Mileage Stats

We chose a pragmatic, progressive enhancement approach when developing forms for Mileage Stats.

As the Works experience was destined for fairly simple browsers, we began with a base of well-structured native HTML form elements. The example below shows a label and input field for the odometer value in the New Fill-up form.

<label for="Title">Reminder title</label>
<input type="text" placeholder="Reminder title" value="" name="Title" maxlength="50" id="ReminderTitle">

We then enhanced this base with carefully chosen HTML5 input types. The example below demonstrates the addition of the HTML5 placeholder attribute in the Reminder title field of the Reminders form.

<input type="text" placeholder="Reminder title" value="" name="Title" maxlength="50" id="ReminderTitle">

HTML5 input types and attributes such as these were chosen based on their support level on our target browsers, and their ability to degrade gracefully (even on much older browsers). The following section outlines our decisions regarding many useful HTML5 types and attributes including number, placeholder and date.

Improving the input of numbers

We used the number input type to improve the user experience on supported browsers. Using this input type triggers a numeric keyboard on many touch browsers, and constrains keyboard input to numbers only on many QWERTY or T-9 devices. This input type degrades gracefully and will simply default to the traditional keyboard when unsupported.


The number input type in action on the iOS platform

The following example demonstrates the addition of a number input type for the Price Per Unit input field in the Fill-up form.

<input data-val="true" 
       data-val-number="The field Price Per Unit (ex. 3.75) must be a number." 
       data-val-range="The price per gallon must be between 0.1 and 100." 
       data-val-required="Price per unit is required." 
       value="0" />

This example shows the HTML5 placeholder attribute used in conjunction with the number input type. Combining these two is prohibited by W3C specification, but testing seemed to indicate that most browsers either supported simultaneous use, or simply omitted (and gracefully degraded) the placeholder. We therefore chose to continue using these together but would recommend further testing before widespread implementation. See Fallback strategies and false positives for more details.

Specifying placeholders

We used the placeholder attribute to display hints within many user input fields but encountered problems due to its incompatibility with the number input type. See Providing input field hints for more details.


Placeholders in the Price per unit, Total units and Transaction fee fields

Form validation

We chose not to implement HTML5 form validation, as support for this feature on target browsers was poor and the specification insufficient for our particular needs. We also already had robust server-side data validation in place using ASP.NET for the Works experience, so it was fairly trivial to implement a client-side alternative using JavaScript on devices that supported our Wow experience criteria. The Wow experience is discussed in Experience categories and enhancements in "Mobilizing the Mileage Stats App."

Improving the input of dates

We chose not to implement the HTML5 date input type, as support was inconsistent on our target browsers. See Fallback strategies and false positives for more details.

Specifying date ranges

The Mileage Stats charts view displays a series of mileage and performance charts based on a range of dates provided by the user. This at first seemed like an ideal opportunity to implement the range input type, which on many browsers displayed a slider mechanism whose handle can be dragged to choose a value. One of these sliders could (in theory) have been used to specify a "To:" date and a second one used to specify the "From" date.

We decided, however, that the support for this property was still insufficient on target browsers. We were also unsure a slider would be the best mechanism for our purposes. A slider can be difficult to manipulate on a small screen so it is most useful when it contains a small number of increments. After several years of use, the chart sliders might contain many dozens of intervals, making it harder to distinguish between each date.

We instead implemented the range feature using two select menus, each prepopulated with a month and date value.


The date range option, implemented using select menus

Styling form elements

Given the diversity of browsers and devices, a key rule when styling form elements is to keep things simple. Browsers already provide a default style for each form element and retaining these often provides the more consistent experience amongst devices.

  • Ensure your form’s markup is well structured and uses semantic elements where these exist. For example, be sure to use <label> elements for all form labels, instead of less semantically relevant paragraph, header or div elements.
  • Begin by testing your form on key browsers using only basic, browser-default styling. There is quite a bit of variety in the styling of certain form elements, so it’s important to begin with an understanding of each form element’s’ default state. This step can prevent you from wasting time later debugging differences that may look like bugs, but may be beyond your control.
  • Add form styling gradually and retest frequently. This may feel like an additional step, but form elements are often the trickiest HTML elements to style. Appling styles gradually can help catch problems early and reduce the need for extensive debugging at a later date.
  • Where possible, take screenshots of default form elements behavior. This will provide a useful reference for your test team and avoid the filing of unnecessary bugs.

Fallback strategies and false positives

Due to the wide fragmentation in form input types, it’s important to consider what will happen in cases where the specification isn’t fully implemented (or behaves unexpectedly). We encountered this several times during the development of Mileage Stats.

Inputting a date

Choosing the most appropriate method for all our users to enter a date proved challenging. The simplest, and most consistent date input method is to provide three select menus (one each for the day, month and year). The select form element is well supported and benefits from a well-designed native component—even on much older browsers. Using a select menu also simplifies validation, as the user can only input values contained within these menus.

On certain newer devices however, specifying an HTML5 date input type would display a custom calendar widget, improving the experience even further. A calendar widget may be better for the user, but knowing when it’s safe to use one poses a problem. It’s possible to detect support for this input type using a JavaScript feature test, but due to spotty implementation, a large number of devices return a false positive. These devices pass a feature test for the date input type, but only display a simple text input field.

We therefore had two choices:

  • We could use the simplest and most consistent form element for everyone.
  • Or, we could improve the experience for certain users, while making it far worse for others.
A third but far more maintenance-intensive solution would have been to create an approved list containing devices that we knew supported the date input type. We would serve the simple select menu to most devices, and the custom HTML5 date element markup to devices on our approved list.
We eliminated this option, however, as it seemed too cumbersome, did not fully comply with progressive enhancement principles, and would require ongoing checking and reformulating of the approved list.

In the end, we decided to implement the simplest and most consistent option: three select menus.


The final implementation using three select menus on Windows Phone 7.5

Providing input field hints

Another HTML5 form attribute that caused problems was the placeholder. This attribute enables developers to specify an input hint that will be automatically visible to users. This hint is typically displayed (often in greyed-out text) within the input field itself, but disappears once the user taps or selects the field to begin typing.

According to W3C specification, this attribute cannot, however, be used alongside the number input type.

We were therefore forced to choose between triggering a numeric keyboard for certain users, or providing a placeholder within those input fields. We were not, however, guaranteed that all users would receive either of these benefits, and expected both to be unsupported on most Works devices.

Our decision was made easier by our initial choice to develop the app following principles of progressive enhancement. The input forms had been constructed using a base of well-structured HTML, and already included form labels and input hints within the markup. So while the HTML5 placeholders were more attractive (and included the useful behavior of disappearing once the user tapped the field) they were not absolutely necessary, given that the input field label already provided this information.

We discovered through testing that most browsers either supported simultaneous use, or simply omitted (and gracefully degraded) the placeholder. We therefore chose to continue using these together but would recommend further testing before widespread implementation.

Creating custom input widgets

During development, we also discussed the possibility of creating our own input widgets. Building custom widgets often seems like a good option, as it enables full freedom over the design, functionality and integration of these widgets. There are, however, several drawbacks to this approach—especially given the wide fragmentation in mobile browsers.

  • Creating your own widgets to input date, color, range, and so forth is time consuming. Ensuring cross-platform compatibility will require extensive testing, and these tests will need to be repeated with each new platform or browser update. You may also need to review your interaction model to suit unexpected new browsing methods—for example, the use of a remote control or Xbox Kinect-style gestures on an Internet-enabled TV.
  • If your widget doesn’t work on a user’s browser there may be no natural fallback mechanism. The user may simply be stuck.

Unless you plan to support only a few browsers, or have considerable testing and development resources at your disposal, it’s best to avoid rolling your own widgets and opt to provide the best experience you can using the existing (and usable) HTML form elements.

Frameworks and libraries such as Sencha Touch and jQuery Mobile include custom input components. These can be useful if you wish to provide a custom experience but do not wish to develop one on your own.


Inputting data on small, resource-constrained devices can be difficult. Your primary goal should be to simplify this task as much as possible.

Use HTML5 input types where you can, but be pragmatic. Test thoroughly to ensure features work as expected and ensure fallbacks are in place to plug the gaps. Avoid implementing custom components unless you have the time and resources to thoroughly test and maintain them.

In the end, your users (and team) may be far happier with old fashioned markup that is easy to construct and maintain, and expected to work on most devices.

Last built: June 5, 2012