Your forms just got easier to use. HTML5 browsers include new controls such as the date
input type, the <range>
tag, and others.
We’ve been talking about form elements for the past few hacks now, and they all have a common thread when it comes to reasoning. Many of these simple, easy-to-implement specifications actually replace standards that web developers have been coding to for years. This has made life easier for developers, made pages perform more quickly (browser code instead of JavaScript), and brought uniformity across web applications.
Let’s focus on uniformity for a bit. For example, let’s look at the date
input type. In the past, web developers have developed a date picker standard similar to the one shown in Figure 1-5, which is from the popular YUI library.
This is a huge improvement over having the user enter the date into an input field and hoping that it meets the required format. With the YUI date picker, we can stylize the component with CSS and make it look like it blends right in with our app. This has served our purposes for years. Whether we are using the Internet Explorer browser or the Firefox browser, our date picker will look the same and the user will always know what to expect.
Along comes mobile. Mobile browsers, for the most part, surf the same Web as our desktops. If you come across this same date picker on an iPhone, this previously great experience becomes difficult. Since the component has no awareness of the native content (it has a small screen in this scenario), it can’t adapt to its context. Many keen JavaScript Ninjas have already started to think about how they can use the User Agent Declaration (part of the request) to customize this date picker for the context of each known user agent. This is a great idea, and many of our polyfill libraries, such as YUI, are a step ahead and provide concessions for small screens. Unfortunately, the only way to do this without HTML5 is to add more code. And more JavaScript, more markup, and more CSS equals page bloat and additional memory usage. Let’s use that extra code and memory for something spectacular and leave the basic input functionality to the browser. Each of the following form features takes something that used to be hard to do in JavaScript and makes it easy, light, and context-aware.
The date Input Type
The date
input type is one of my favorites. As in the previous date picker example, a lot of work has gone into creating a successful date selection tool. I can’t tell you how many times I’ve been frustrated with parts of the Web that use date selection tools that are slow and buggy (yes, I mean you, airline and car rental sites).
The HTML5 date
input type is fairly simple to implement. Out of the box it looks something like this:
The preceding code results in the simple pull-down box shown in Figure 1-6.
In terms of context, here’s the great thing about the preceding example. As it stands, the date selector will be pretty tough to use on my iPhone; not only is it hard to see, but also my fingers are pretty fat and those tap zones are pretty small. So in iOS 5 and later, Apple has kindly implemented the date input field shown in Figure 1-7.
Nice job, Apple! Now let’s look at some of the other attributes we can add to give this application a functionality similar to those great little polyfill date pickers. Here’s the code:
Let’s look at some of these in more detail:
step
Increment at which a date can be selected. The spec doesn’t clarify all the increment types that a user agent must adhere to, but day, week, month, and year are obvious implementations.
min
A date value that represents the minimum date the input will consider valid. It’s not clear whether the controller will allow you to choose dates below the
min
date, or whether it limits selection to the valid date range. Implementations differ among browser makers at this point.max
A date value that represents the maximum date the input will consider valid.
As is the case with all changes that are powerful, a new set of DOM methods has been added as well:
stepUp()
/stepDown()
Can be called to increment the date that is input to either the next date or the preceding date in the series.
stepUp()
calls the next day;stepDown()
calls the preceding day.valueAsDate()
Returns a JavaScript date object, not just a date string.
This might not sound exciting, but you can replace this polyfill:
with this:
It’s also interesting to note that there are a few variations on the input type of date
, and each provides noteworthy interface challenges, especially on mobile and touch devices. Here are some similar types to keep your eye on:
datetime
month
week
time
datetime-local
The range Input Type
Once again, let’s look at one of our great polyfill libraries to get an idea of what the problem is. Figure 1-8 shows a screen capture of the YUI slider utility.
When you’re selecting ranges, nothing is worse than typing in values, especially when you’re “exploring” what will happen when those ranges change. The slider has become a standard tool on both web and desktop devices. You generally have a bar representing something like numeric values or colors, and a handle that you drag from one end of the bar to the other. Again, let’s consider how difficult it may be to make selections on the YUI slider if you’re on a mobile device. The handle is small, and what feels like a short amount of movement on a mobile device could be a sizable amount to the slider.
The HTML5 type of range
allows browser makers to provide a range selection tool with an experience that best fits the context of the device. The pattern for desktop browsers appears to be a slider. Let’s jump into the implementation:
All that, with no JavaScript—this polyfill would be hundreds of kilobytes’ worth of code. Now let’s look at some of the attributes we added to the input:
min
/max
Once again we see the ability to set a
min
and amax
for the range. These are a bit more profound in therange
input type because they define the first step (the bottom of the slider) and the top (the top of the slider). If nomin
andmax
are set, the user agent (again, the browser) will assume the range is 0 to 100.step
In the preceding example we are selecting shoe sizes that come in half or whole sizes. Therefore, we set the
step
to.5
so that whole or half sizes can be chosen. This can come in handy in very large ranges as well. Say you are applying for a loan and you’re using a range tool to choose your loan amount. For an improved user experience, you may want to round up to the nearest $10,000. Setting thestep
to10,000
will allow you to do just that.value
We’ve seen
value
hundreds of times when it comes to input: it allows us to set the initial value of that input. It’s of particular interest on therange
input type, because there is no “null” value. Since it is a slider, there is no point at which the value would be undefined, so the user agent will choose a reasonable default value for you—something in the middle of the range. In our example, we chose ourvalue
to be3
since the most popular shoe size in our little store is size 3. (Yes, we do cater to elves, leprechauns, and small children.) Thevalue
allows you to choose the “default” value that makes the most sense, not just what’s in the middle.
The HTML5 version of the sliders also has the added benefit of being able to match the other browser controls, as shown in Figure 1-9.
It’s also interesting to note that the range tool can be tied to a datalist
(we discussed this briefly in [Hack #4]). The datalist
could include non-numeric values or unequal numeric values that can be selected within the range. I haven’t seen any browser makers implement this yet, but it will be interesting to see some possibilities.
The color Input Type
You may not have thought of a color picker as being essential to a user’s web experience, but as the Web becomes more of an application environment, complex activities such as picking colors need to be responsive and adaptive. The color
input type allows you to select a color value from within the input.
Support for this input type is still nascent, and at the time of this writing no user agent supports it. As with all of the other unsupported input types, browsers that do not (or do not yet) support the color
input type will simply see an input tag as it would appear for an input with the type
equal to text
.
The <meter> and <progress> Tags
Moving slightly out of the input space but staying within the HTML5 form, we see two new form components that will quickly become basic building blocks for web applications. The first of the two is the <meter>
tag. For a clear definition, let’s go right to the spec:
The meter element represents a scalar measurement within a known range, or a fractional value; for example disk usage, the relevance of a query result, or the fraction of a voting population to have selected a particular candidate.
Think of a meter as a bar from a bar chart. It’s a graphical representation of one number as part of a greater number. Let’s look at a code example:
The preceding code would result in something like Figure 1-10.
This particular form element has some interesting UI controls. You can see from the preceding example that the meter needs to have a value set, as well as a range, to be effective. The min
and max
attributes will set the range (the meter is completely empty and the meter is completely full, respectively), and the value
will specify the current fill level. If either of the attributes is missing, the form will assume the value—for example, an undefined value will probably be considered zero by most user agents.
Additionally, three other attributes can be added to the meter to control the interface. The optimum
value would display a graphical representation of what the ideal value would be. The low
and high
attributes are for setting thresholds when your meter is below or above the optimal range. The interface should respond accordingly; current browser implementations turn the meter color to yellow for “low” and red for “high.”
The <progress>
tag is also new for HTML5 forms. Think of the <progress>
tag as the bar that pops up when you’re downloading a file to tell you how much longer you have to wait. It might look something like Figure 1-11.
The code implementation would be as follows:
The <progress>
tag has only a few configuration attributes, and both are shown in the preceding code. The first is the max
attribute that tells you what your progress “goal” is. The max
value will be the top of your meter; the bottom will always be zero. Your value
will then specify the progress, and thus, how much of the progress bar is filled.
Once again, these two new tags are examples of web standards that traditionally were implemented with JavaScript and CSS but can now be accomplished directly through HTML5. Each tag should look appropriate for the context of the application.
Form Elements and Making Them Look Good
One thing all form elements have in common is that they look bad. Since I first started working with forms nearly 15 years ago, I’ve been trying to find ways to make them look better. A perfect example of this is the drop-down menu. Drop-downs look pretty simple. However, it’s difficult to do anything special with them, such as adding help text to the options or controlling the width of the menu while it has options with a lot of text in them.
HTML5 and CSS3 bring us some good news and some bad news. The good news is that we can use CSS to control a lot of the treatments we’ve looked at in this hack. The bad news is that we can’t control all of them. Let’s look at a few examples.
In the preceding example, we have a number
input type with some funky spinner buttons on it to increment and decrement the number. We don’t want the funky buttons, so in CSS we specify (with browser prefixes) the subcomponents we want to alter. In this case they are -webkit-inner-spin-button
and -webkit-outer-spin-button
. We are simply hiding them in this example.
Browser makers are adding flexibility for many form controls. Most browser makers allow you to alter the look of the validation error pop-up windows as well. Some components, such as the date
and color
input types, may not have CSS subcomponent controls.
Keep in mind that this control is both good and bad. It’s good when you just don’t like the experience presented by the user agent and you need to update the look and feel on your own. In contrast, it’s bad to makes changes to these elements because they then lack the ability to adapt to the context in which they are being used. Remember the drop-down menu I complained about earlier? Well, iOS has found a way to turn it into a brilliant user input on the iPad and iPhone. On the iPhone it becomes a spinner input at the bottom of the screen (see Figure 1-12). On the iPad it becomes a drop-down window in the context of the Select Box. In both cases, the input is well suited to its context. If you had CSS overrides on these components, who knows what the experience would be like for the end user on an iOS device.
In Conclusion
Now that we’ve explored the inner workings of forms, you should be ready to dive into some HTML5 applications. Forms are still the basic building blocks of pages, and to understand forms is to understand HTML5. So let’s get going and dig in!
0 Comments: