Working with HTML forms can be somewhat daunting. They not only use some niche HTML elements, but also blur the line between static content and user interaction. Let’s review some things to remember when creating your next form.
Good HTML forms require attention on at least four points:
- semantics
- accessibility
- functionality
- design
Forms can be difficult and sometimes even annoying for users; often, a form interrupts a user’s main focus and direction on a page: they’re intent on purchasing that gift, or trying out your new web app, not giving you their shipping address or coming up with yet another password. These tips will make forms easier for you as a developer or designer, and for them as users.
Semantics
1. Use fieldset
to Encapsulate Similar Fields
Generally, forms are made up of inputs inside form tags. When you’ve got a lot of fields that the user must fill out, it can be easier for both the user and you, the developer, to keep track of input by using fieldset
. The perennial example of this is using fieldset
to separate a billing address and a shipping address.
<fieldset> <span>Billing Address</span><input type="text" /> <span>City</span><input type="text" /> <span>Province</span><input type="text" /> <span>Postal Code</span><input type="text" /> </fieldset> <fieldset> <span>Shipping Address</span><input type="text" /> <span>City</span><input type="text" /> <span>Province</span><input type="text" /> <span>Postal Code</span><input type="text" /> </fieldset>
2. Label fieldset
with Legends
It hardly makes sense to use a fieldset
without giving it a clear name. We can improve the code above by using the legend element to title our fieldset
. The fieldset
element has a border by default, and the legend will lay itself over that border.
<fieldset> <legend>Billing Address</legend> <span>Address</span><input type="text" /> <span>City</span><input type="text" /> <span>Province</span><input type="text" /> <span>Postal Code</span><input type="text" /> </fieldset>
This results in the following:
3. Name Your Inputs
If you want to pass form data to a script, each input element needs to have a name; if you are using PHP, these names will become the keys to a super global array, usually $_POST
or $_GET
.
<fieldset> <span>Billing Address</span><input type="text" name="billAddress" /> <span>City</span><input type="text" name="billCity" /> <span>Province</span><input type="text" name="billProvince" /> <span>Postal Code</span><input type="text" name="billPC" /> </fieldset>
4. Use the label
Element
Let’s continue improving that code. There’s nothing inherently wrong with using a span
to label the inputs, but the label
tag is a born match for inputs.
<fieldset> <legend>Billing Affress</legend> <label>Address</label><input type="text" name="billAddress" /> <label>City</label><input type="text" name="billCity" /> <label>Province</label><input type="text" name="billProvince" /> <label>Postal Code</label><input type="text" name="billPC" /> </fieldset>
5. Give Labels the for
Attribute
I really like the for
attribute. It provides a way to bind a label to an input. The value of for
should be the same as the id
of the input you want to bind it to.
<fieldset> <legend>Billing Affress</legend> <label for="billAddress">Address</label><input type="text" id="billAddress" name="billAddress" /> <label for="billCity">City</label><input type="text" id="billCity" name="billCity" /> <label for="billProvince">Province</label><input type="text" id="billProvince" name="billProvince" /> <label for="billPC" >Postal Code</label><input type="text" id="billPC" name="billPC" /> </fieldset>
At first, this is one of those things that only seem to affect your code’s quality, but they do a special job in the visible content. When the for
attribute is defined, the label becomes a ‘clickable’ area that will focus the input. For example, clicking the label of a text
input will focus your cursor in the box; clicking the label of a checkbox will check (or uncheck) the box.
6. Use optgroup
to Categorize Options
If you have a lot of options in a select, it’s usually better to group them into optgroups. The optgroup
is a little-known element that will indent options and give them a title. Note that the label
attribute is required.
<select> <optgroup label="USA"> <option>Alabama</option> <option>Alaska</option> <option>Arizona</option> </optgroup> <optgroup label="Canada"> <option>Alberta</option> <option>British Columbia</option> <option>Manitoba</option> </optgroup> </select>
This gives us the following results:
7. Specify Input Types
The type
attribute for input
fields in HTML5 can have many different values. This can help with basic input validation as well as show users different keyboards when they are using mobile devices to fill out the form.
You can read about all these input types in the MDN article about HTML5 input types. Two things that you should keep in mind are that not all browsers fully support every input type and the UI for the same input type might differ across browsers.
8. Consider Using Buttons Instead of Submit Inputs
Generally, <input type="submit" />
has been the universal submit button. But HTML has a button
element. Why would you use it? Well, it’s generally easier to style buttons; also, you can put images within a button, so it really offers more flexibility. You can read more in these two articles.
Accessibility
9. Put Tab Indices on Your Inputs
It’s definitely easier to tab through a form than it is to use your mouse. However, by default, your user will tab through in the order they are written in the HTML. If this isn’t the order you want them to go through the inputs, you can easily add the tabindex
property to your inputs. The tabindex
attribute takes a number value, and will hop to the input
with the next highest value when you hit that Tab key.
<input type="text" tabindex="2" /> <input type="text" tabindex="1" /> <input type="text" tabindex="3" />
10. Define accesskey
When Appropriate
The accesskey
attribute creates a keyboard shortcut that will focus that input. The shortcut is Alt (Option) + the accesskey
value. Obviously, you wouldn’t put an accesskey
on every input, but it would certainly be useful on, for example, a search box. Don’t forget to let users know about the shortcut. Often this is done by underlining the letter, as it’s usually part of the label.
<label for="search"><span class="shortcut">S</span>earch</label> <input type="text" name="s" id="search" accesskey="s" />
11. Use Good Focusing Techniques
You could argue that this point is as much on the side of design as it is accessibility. It’s always nice if a form field (usually a text box, in this case) changes color when it’s focused, but for the visually impaired, it’s almost a requirement if they are to use the form successfully. To this end, you can use the hover psuedoclass in your CSS. You can also use JavaScript for this. Note that jQuery has a hover event.
input[type=text]:hover { background-color:#ffff66; border-color:#999999; }
12. Consider People Using Screen Readers
Since forms have the tendency to be so tedious, everyone likes a well-designed form. But don’t let a fancy form ignore screen readers. Always make sure your inputs are clearly labeled. If you don’t want those labels to show (maybe you are labeling text inputs with values that disappear on focus), you can remove them from the visual presentation (don’t use display: none
, though; there are better ways). Also, screen readers generally associate the text directly before an input to be the label for the input. The exceptions to this are radio buttons and checkboxes.
13. Use the placeholder
Attribute
The placeholder
attribute comes in handy when you want to quickly show your users what kind of input you expect them to provide. The text you provide as example for any input element is displayed using text with a lighter shade. Try to avoid repetition when using this attribute. For example, if the label of the input element already shows the text Your Email don’t put it in the placeholder as well. The placeholder value should be something like [email protected].
Functionality
14. Use the Right Content Type
In most cases you won’t need to put the enctype
attribute on your form
tag. It will default to application/x-www-form-urlencoded
. However, when you have a file input, which will allow the user to upload the file, you need to use multipart/form-data
.
<form action="verify.php" method="get" enctype="multipart/form-data"> <label for="avatar">Upload your Avatar : </label> <input type="file" name="avatar" id="avatar" /> </form>
15. Know When to Use GET and When to Use POST
A form can send its data by two methods: GET and POST. You define one in the method attribute on the form
tag. What’s the difference, and when should you use them? Ignoring what goes on at the server, the main difference is the way the browser sends the information. With GET, the form data is sent as a query, visible in the URL.
<form action="you.php" method="get"> <label for="fname">First Name</label> <input type="text" name="fname" id="fname" value="Bill" /> <label for="lname">Last Name</label> <input type="text" name="lname" id="lname" value="Gates" /> </form>
So the form above would result in this URL when submitted: http://www.example.com/you.php?fname=Bill&lname=Gates
When you use POST, the data is sent in the HTTP request header. That way, it’s not visible to the average user. So which should you use when? POST is better for sensitive data (like passwords) and any data that will generally change something (eg. adding a record to the database). Also, POST is your only option if you’re uploading a file. GET is great for querying the database, and other requests that don’t have a lasting affect on anything (“idempotent” requests, the spec calls them). Really, I’ve just scratched the surface on the differences here: there are other articles that go into this in-depth.
16. Validate on Both the Client and Server
Validation is the bane of forms. But it’s best to check the input both on the client and on the server; validating in the browser allows you to warn the user of mistakes before they submit the form, which requires one less transaction with the server. However, always be sure to validate on the server as well, for security’s sake.
17. Use HTML5 Attributes for Validation
There are quite a few useful attributes in HTML5 that make form validation a breeze. For example, you can use the minlength
and maxlength
attributes to specify the minimum and maximum number of characters that would be considered valid for any input element. Another such important attribute is pattern
. It gives you the ability to specify what is considered valid input using regular expressions.
We have written a tutorial about HTML5 based form input validation in the past. It will give you a brief summary of all available validation attributes.
18. Use the datalist
Element
The datalist
element is a great way of providing users some valid input options. However, they are not limited to using your suggestions as the only values. This element simply provides them a hint about what types of values you expect. It also helps them fill out the form quickly in case what they want to enter is already listed by you. Here is some markup to show you how to use this element in your forms.
<label for="holiday-choice">Choose Your Favorite Holiday:</label> <input list="holiday-names" id="holiday-choice" name="holiday-choice" /> <datalist id="holiday-names"> <option value="New Year's Day"> <option value="Independence Day"> <option value="Halloween"> <option value="Thanksgiving"> <option value="Christmas Day"> </datalist>
As you can see, the datalist
element has to be used in conjugation with an input element. They are hooked together using a list
attribute on the input and an id
attribute on the datalist.
19. Give Your Users Smart Warnings
This goes hand in hand with the previous best practice. Too many times I’ve submitted a form only to be told Fields were not filled correctly. Can you spell vague? Once you’ve determined that your user has made a mistake, let them know as soon and as clearly as possible. Put your error messages close to the bad field, and let your user know what’s wrong with their entry. I like using the jQuery’s blur()
event for this. As soon a user hops to the next box, the previous one is validated.
20. Consider Using AJAX to Submit
Many times, submitting a form results in a simple message: Thank you, Check your email for confirmation, or We’ll get back to you when we can. When that’s the case, what better place to use AJAX? You could just fade out the form, send the data with jQuery or some other library, and fade in your message.
21. Make Sure Your Form Works Without JavaScript
Maybe this should have gone under accessibility. Although the last couple of tips need JavaScript, make sure your form is completely functional without them. This means a regular form submit, server-side validation, and good errors after a page reload.
Design
22. Style Forms Consistently
I’m no designer, and I don’t pretend to be, but I do know this much: don’t fling your form fields carelessly around. Your form should be consistent in its styling. Decide whether your labels will be to the left or right (or perhaps above or below) of the fields, and stick with it. Make all your text inputs and textareas the same width. Space all your fields equally. Keep at least one edge of all boxes aligned.
23. Style Form Elements With CSS
Different browsers usually have their own unique style for displaying form elements. Sometimes you will need to use JavaScript to provide consistent UI for complicated elements across browsers. However, you can still use a few pseudo classes like :valid
, :invalid
, :required
and :optional
etc. introduced in CSS3 to style different states of your form elements.
24. Be Inspired by Others
Forms don’t have to be visually unappealing. Designing a great looking form definitely requires some extra effort but it can totally be worth the extra work if you get some extra registrations etc. It is always helpful to make sure that the styling of your forms matches the overall look and feel of your website.
You can take a look at some form examples on CodePen if you want inspiration. There are a lot of form builder scripts on CodeCanyon as well to speed up the process of creating a form.
-
PHPCreate Beautiful Forms With PHP Form Builder
-
PHPComparing the 5 Best PHP Form Builders (And 3 Free Scripts)
Final Thoughts
Website forms can be challenging, but I hope these tips will help you make your forms stand out from the rest. Have a good tip that I didn’t mention? Let’s hear it in the comments!
You Also Might Like
-
PHP30+ PHP Best Practices for Beginners
-
JavaScript23 JavaScript Best Practices for Beginners
-
HTML & CSS30 HTML Best Practices for Beginners
This post has been updated with contributions from Monty Shokeen. Monty is a full-stack developer who also loves to write tutorials, and to learn about new JavaScript libraries.