HTML5 Forms: Input Types (Part 2)

By Alexis Goldstein , Estelle Weyl , Louis Lazaris

The following is an extract from our book, HTML5 & CSS3 for the Real World, 2nd Edition, written by Alexis Goldstein, Louis Lazaris, and Estelle Weyl. Copies are sold in stores worldwide, or you can buy it in ebook form here.

You can find Part 1 here.


The number type (type="number") provides an input for entering a number. Usually, this is a spinner box, where you can either enter a number, or click on the up/down arrows in a native browser spinner UI to select a number.

Let’s change our quantity field to use the number input type:

<label for="quantity">I would like to receive <input type="number" 
↵min="1" name="quantity" id="quantity"> copies of 
<cite>The HTML5 ↵ Herald</cite></label>

Figure 4.8 shows what this looks like in Opera.

Figure 4.8. The number input seen in Opera

On many touchscreen devices, focusing on a number input type will bring up a number touch pad (rather than a full keyboard).

The number input has min,
max, and step attributes to specify the minimum, maximum, and incremental values allowed. If the step is omitted it defaults to 1.
If you would like to allow float values, you must specify a float step, such as 0.1 or the keyword any to allow for any value. Note that some browsers will minimize the width of the number form field for restricted numbers. For example, min="0" max="10" step="1" doesn’t need to be as wide as step="any", where the user could enter the full value of Pi.

Warning: Use number with Caution

There will be times when you may think you want to use
number, when in reality another input type is
more appropriate. For example, it might seem to make sense that a
street address should be a number. But think about it: would you
want to click the spinner box all the way up to 34154? More
importantly, many street numbers have non-numeric portions: think
24½ or 36B, neither of which work with the number
input type.

Additionally, account numbers may be a mixture of letters and numbers, or have dashes. If you know the pattern of your number, use the pattern attribute. Just remember not to use number if the range is extensive or the number could contain non-numeric characters and the field is required. If the field is optional, you might want to use number anyway, or tel in order to prompt the number or telephone keyboard as the default on touchscreen devices.


The range input type (type="range") displays a slider control. As with the number type, it allows the min, max, and step attributes. The difference between number and range, according to the spec, is that the exact value of the number is unimportant with range. It’s ideal for inputs where you want an imprecise number; for example, a customer satisfaction survey asking clients to rate aspects of the service they received.

Let’s change our registration form to use the range input type. We’ll create a field asking users to rate their knowledge of HTML5 on a scale of 1 to 10:

<label for="rating">On a scale of 1 to 10, my knowledge of HTML5
<input name="rating" type="range" min="1" max="10" step="1">

Figure 4.9 shows what this input type looks like in Safari. In this case the step attribute is not required, as it defaults to 1. A negative value for step will break the range by making the thumb immovable in Firefox.

Figure 4.9. The range input type in Safari

The default value of a range is the midpoint of the slider—in other words, halfway between the minimum and the maximum. Including the list attribute with an associated datalist enables creating little notches along the slider path showing the location of the suggested values.

The spec allows for a reversed slider (with values from right to left) if the maximum specified is less than the minimum; however, no browsers currently support this. Additionally, the spec allows for two thumbs with the inclusion of the multiple attribute. No browsers support this either.

range is supported in all browsers, starting with Firefox 23, Android 4.2, and Internet Explorer 10. list support on the range input type is currently only found in Chrome 20+, Opera, and Internet Explorer 10+.


The color input type (type="color") provides the user with a color picker—or at least it does in some browsers, including BlackBerry 10, Firefox 29+, Safari 8+ for desktop, Chrome, Opera, and Android 4.4. WebKit for iOS 8 and Internet Explorer 11 are yet to support the color input type. The color picker returns a lower-case hexadecimal RGB color value, such as #ff3300, with the default value being #000000 (black).

If you want to use a color input, provide placeholder text indicating that a hexadecimal RGB color format is required, and use the pattern attribute to restrict the entry to only valid hexadecimal color values.

We don’t use color in our form, but if we did, it would look a little like this:

<label for="clr">Color: </label> 
<input id="clr" name="clr" type="color" placeholder="#ffffff" 

The resulting color picker is shown in Figure 4.10. Clicking the Other… button brings up a full color wheel, allowing the user to select any hexadecimal color value. If you’re after other colors, use the list attribute with an associated datalist to define each color you want to suggest as individual options. This is currently supported in Blink browsers only.

Figure 4.10. Chrome’s color picker control for the color input type

Dates and Times

There are new date and time input types, some of which are included in the HTML5 specification, as well as a few others that are still listed in the HTML Living Standard and the HTML5.1 draft that may be at risk. The date and time input types made it into the HTML5 W3C Recommendation, while datetime, datetime-local, month, and week are at risk of being dropped. All date and time inputs accept data formatted according to the ISO 8601 standard.

Here are the available date and time input types:

  • date: comprises the date (year, month, and day), but no time; for example, 2004-06-24.
  • time: signifies a time of day using the military format (24-hour clock); for example, 22:00 instead of 10.00 p.m.
  • month: only includes the year and month; for example, 2012-12.
  • week: covers the year and week number (from 1 to 52); for example, 2011-W01 or 2012-W52.
  • datetime: includes both the date and time, separated by a “T”, and followed by either a “Z” to represent UTC (Coordinated Universal Time) or by a time zone specified with a + or – character; for example, “2011-03-17T10:45-5:00” represents 10:45 a.m. on the 17th of March, 2011 in the UTC minus five hours time zone (Eastern Standard Time). This value has been removed from the spec and then added back in. It is currently without support.
  • datetime-local: is identical to datetime, except that it omits the time zone; the main difference is that datetime-local is supported in browsers that support date and time, while datetime is not.

The most commonly used of these types is date. The specifications call for the browser to display date controls. At the time of writing, WebKit for iOS, Chrome 20+, and Opera provide calendar controls for most of these values. Internet Explorer 11, Safari for desktop, and Firefox 37 still do not.

Let’s change our subscription start date field to use the date input type:

<label for="startdate">Please start my subscription on:</label>
<input type="date" min="1904-03-17" max="1904-05-17" 
↵id="startdate" name="startdate" required aria-required="true" 

Now, we’ll have a calendar control when we view our form in Opera, Chrome, or iOS WebKit, as shown in Figure 4.11. Unfortunately, it’s unable to be styled with CSS at present.

Figure 4.11. A calendar control

For the month and week types, browsers display a similar UI as the date input type, but only allow the user to select full months or weeks. In those cases, individual days are unable to be selected; instead, clicking on a day selects the whole month or week. While datetime-local is supported in these browsers, datetime is not. datetime has been deprecated. month, week, and
datetime-local are at risk as well, but have yet to
fall to the same fate. Chrome lost support for datetime in version 26, Opera in version 15, and Safari in iOS7. Instead of using datetime since support should be deprecated, use date and time as two separate input types.

We recommend including a minimum and maximum when using the date input type. As with number and range, this is done with the min and max attributes.

The placeholder attribute that we added to our start date field earlier is made redundant in browsers supporting the datepicker interface, but it makes sense to leave it in place to guide users of IE, Safari, and Firefox until they implement the date and time controls. Until all browsers support the UI of the new input types, placeholders are a good way to hint to your users what kind of data is
expected in those fields. Remember, they’ll just look like regular text fields in nonsupporting browsers.

Tip: Dynamic Dates

In our example, we hardcoded the min and max values into our HTML. If you wanted the minimum to be the day after the current date—which makes sense for a newspaper subscription start date—this would require updating the HTML every day. The best way to handle it is to dynamically generate the minimum and maximum allowed dates on the server side. A little PHP can go a long way:

<?php function daysFromNow($days){ 
  $added = ($days * 24 * 3600) + time(); 
  return date("Y-m-d", $added); 

In our markup where we had static dates, we now dynamically create them with the above function:

  <label for="startdate">Please start my subscription on: 
  <input type="date" min="<?php 
echo(daysFromNow(1)); ?>" 
↵max="<?php echo(daysFromNow(91)); ?>" 
↵name="startdate" required aria-required="true"
↵placeholder="<?php echo(daysFromNow(1)); ?>"> 

This way, the user is limited to entering dates that make sense in the context of the form.

You can also include the step attribute with these input types. For example, step="7" on date will limit the user to selecting only one day per week: the particular weekday depends on the min if one is present, or is the current day of the week if none is present. On time input, the step attribute must be expressed in seconds, so adding step="900" on the time input type will cause the input to step in increments of 15 minutes.

Get the latest in Front-end, once a week, for free.