HTML5 brings many great features that we can start using now, and many of them lie within forms and inputs. Some HTML5 enhancements often require fallbacks for our projects, through polyfills or fallbacks. In this tutorial, we’ll create a contact form that will include the following features:
- HTML5 input attributes
- HTML5 enhanced input types
- HTML5 semantics
- HTML5 data-* attributes
- Fluid and responsive design
- HTML5 fallback setup
HTML5 introduces a few new attributes that we can add to our inputs, but first let’s look at our labels. The <label> element is critical to keeping the user experience of your website easy for users, the last place you want to trip people up is contacting you. So what we do is keep our labels outside of our form inputs as this can be bad for the user’s experience. The issue with keeping labels looking like they’re inside the form field is; when the user starts typing, the meaning of the input is removed and is no longer visible. This is why labels are best kept outside of the inputs, preferably above or beside.
A properly setup label and input looks like this:
Alternatively, you can link a form and input like this (using ‘for’ and the ‘id’ to link them):
I prefer the first method, as it saves markup and allows more control of the elements.
We wrap the <label> around the <span> and <input> tags, which allows the user to actually ‘click’ on the label text and their cursor will automatically focus on the corresponding input field. Using CSS, we can add a hover style so that when the user hovers over the text, they know they can also click it to focus the input field, as they’re not always easy to focus on. The <span> tags are added for styling purposes.
Next we can look at the HTML5 placeholder attribute, which allow us to hint more information as to what the field is about and what the user can do with it. Under no circumstances must you simulate the label as the placeholder, sure it’s a lot easier to do, but semantically it isn’t correct and usability is bad. Setting a placeholder can be done like so:
Now we’ve enhanced our form a little more, let’s look at the updated HTML5 tabindex attribute. Tabindex predates HTML5, but has limitations as to it’s valid use. The HTML5 tabindex attribute can be used on any element. Using the tabindex allows us to set the order in which the user can tab through the form fields. Logically, these should be set in a chronological order, but for forms that have multiple levels or columns, you could control the order of these should you wish to direct users to certain fields before others. They also help aid mobile experience. Let’s add a tabindex to our form:
Required fields are also an important aspect of validation and getting the necessary information from your users. From a usability perspective, you’ll want to hint to the user, preferably next to the label, that the field is required. HTML5 introduces the ‘required’ attribute, which can be added in multiple ways, which all mean the same thing:
The required attribute triggers behaviour in the browser, instead of the developer having to setup an alert, or text to show the validation error has occurred because the field is required.
Now we’ve got some great fields setup, let’s look how can enhance it further and help out the end user. If your HTML5 form is above the fold, it’s possibly a good idea to use the ‘autofocus’ attribute, to save the user the hassle of having to focus in on your first input field. The page will load with the specified input field automatically focussed. Putting the above together, we can then create a fuller markup like so:
Now we’ve added some great attributes to enhance the inputs, let’s look at changing the input types to HTML5 input types to enhance mobile experience too. We have a lot of new input types to play with in HTML5, some we’ll be using are ‘email’, ‘tel’ and ‘url’. This is how they would work in the markup:
These three input types tell the browser what to expect in the field, validating it for you on the fly, and do come in really handy when also using a mobile or tablet. On iOS and Android devices (that I’ve tested), we get a relevant keyboard per each input type. For email, we get an ‘@’ symbol, for url we see the ‘.com’ and for tel it switches to a number keypad. The end user definitely feels valued at this point.
Putting the above together, we can look at the finalised markup, with some heading tags to instruct the user. Instead of using <input type=”submit”> to submit the form, we’ll use a <button> element. This is better and more flexible as you can have HTML content and images inside the , whereas <input type=”submit”> is limited to text only.
In terms of browser compatibility, if the browser doesn’t support the HTML5 input type, it will simply degrade itself to a text input type, which saves us creating a fallback.
To style our form, we’ll use some special CSS selectors to target our fields, instead of giving each an ID or class. Though before we get started styling our inputs, we’re going to rework the CSS box-model with a box-sizing declaration.
The box-sizing:border-box; declaration means that our width now includes any borders and padding. This helps us creating the responsive-ready form at a fluid-width. We’ll be setting the form up with percentages, so that it obeys a 100% width, which means it fits perfectly inside our form wrapper, without box-sizing:border-box; this would be a more complicated situation as form elements tend to be one of the most difficult elements to style. Box-sizing is supported in Internet Explorer 8 and above and is definitely the way forward from a CSS reset perspective. Don’t forget that you’ll also need the viewport meta tag, which is included in the demo and download to let your content fit to the specific screen width.
Back to styling the inputs! Now they’re all setup to perfectly obey 100% widths, no matter the padding or borders, we can add some style using some fancy selectors. Here’s how we can give each form input the same style, no matter the input:
We can then target the <button> in the same way:
CSS3 allows us to style the HTML5 placeholder text colours, which is great for that additional touch. If you’d like to do that you can do the following:
First things first, we need to create a test element:
Next we’ll create an object called ‘supports’ which we’ll test a few features against:
We’ve added a few HTML5 attributes which it’s worth running a feature detection test on, these are;
- HTML5 ‘autofocus’ attribute
- HTML5 ‘required’ attribute
- HTML5 ‘placeholder’ attribute
So let’s add these into our script, and test them against our object.
We then run the attributes through the input, and can test whether they exist like so:
We can of course invert the expression (using a bang – ‘!’) so that it only runs if the browser doesn’t support the attribute:
Let’s setup the script for the rest of our feature detections:
For the ‘required’ attribute, each project will possibly take a different solution, client-side or server-side validation. You can validate with backend code such as PHP, or validate with front-end technology such as jQuery validation scripts or your own custom one.
For the ‘placeholder’ attribute, this one you can either leave as an HTML5-only enhancement, and provide no fallback. It’s not essential as we’ve got the <label> to take care of the top-level information.
HTML5 data-* Attributes Submit
Accessing the data is best done in the most cross-browser way, HTML5 introduces the dataset property, which is lacking feasible support. The best way to access the HTML5 data-* attributes to use the getAttribute(); property, and grab the data-* attribute, for example:
Using this knowledge, we can have a little fun with our Submit button. When a user clicks it for submission, we’ll grab a data-* attribute we’ve added to the Send:
The above script also checks that the element exists on the page, this prevents any errors being thrown. We use a simple if statement to check if the element exists, and if so, setup the onclick function which simply changes the innerHTML on the send button.