Overview
By the end of this chapter, you will be able to use the correct HTML form elements to build an online form; customize form elements to improve the look and feel of your web forms; build online forms; apply form validation styles; and identify when to use checkboxes over radio buttons.
This chapter introduces HTML forms and associated elements used within forms. We will first look at the most common HTML form elements used when building forms. We will then take a look at some common techniques for styling forms. We will then put all of this into practice by building signup and checkout forms for a video store.
In the previous chapters, we studied how to build web pages that contain static text-based content. From this chapter onward, we will learn how to make web pages much more interesting, starting with forms.
Forms allow users to actually interact with a website. They enable users to sign up for services, order products online, and so on. Forms are arguably one of the most crucial aspects of business websites, as without forms no transactions can take place online. Businesses require online forms to capture user details when creating new user accounts, for instance, to allow users to select flight details when booking a holiday online. Without forms, many online businesses would not be able to function. With this in mind, developing complex forms is an essential skill to add to your toolbelt as a web developer.
In this chapter, we will take a look at the most common elements that are used to build forms with HTML. These HTML elements include text inputs, radio buttons, checkboxes, text areas, submit buttons, and so on. Once we've gained an understanding of the most commonly used form elements, we will look at styling concerns. This will include techniques to make our form elements look visually appealing to a wide range of users. We will put all of this into practice by building different online forms.
HTML provides us with a variety of elements that are used for building forms. While browsing the web, you must have noticed that online forms typically have similar elements. Most forms will contain input fields such as text inputs, checkboxes, and select boxes.
In this section, we will look at the following HTML form elements:
The first element we need to know about when creating forms is the form element. This is the outermost element, which contains all other form elements, such as inputs and buttons. The form element requires you to pass two attributes, which are the action and method attributes. The action attribute allows the developer to specify the URL where the form data will go to after it has been submitted. The method attribute allows the developer to specify whether the form data should be sent via get or post. You will typically use the get method when you are dealing with unsecured data since the data will be present in a query string. On the other hand, the post method is typically used when dealing with secure data, or when dealing with a large amount of soft data. The following code snippet shows an example of what an empty form would look like in HTML:
<form action="url_to_send_form_data" method="post">
<!-- form elements go here -->
</form>
Now that we have our form element, we can start building the form using different elements. The first one we will look at is the input element. This is the element you would use when creating text input fields, radio buttons, and checkboxes. The input element is the most important of all the form elements we will look at and you will find yourself using it over and over again. The input element requires two attributes, which are type and name. The type attribute is used to specify what type of input you want, such as radio buttons, checkboxes, or text. The name attribute gives the element a unique name that is required when submitting the form. This is so that the form's data can be organized into key-value pairs with a unique name corresponding with a value. It should be noted that the order that you add the attributes in has no significance. The following code snippet shows how to create a text field using the input element:
<!-- text input -->
<form action="url_to_send_form_data" method="post">
<div>
First name: <br />
<input type="text" name="firstname" />
</div>
<div>
Last name: <br />
<input type="text" name="lastname" />
</div>
</form>
The following figure shows the output for the preceding code:
Sometimes, when creating text inputs, you will want to limit the number of characters a user can add. A common example of this is when you want to restrict the number of characters for a new username in account signup forms. You can use the maxlength attribute and set the maximum number of characters allowed for the input field. The following code snippet shows how you would use this attribute:
<input type="text" name="username" maxlength="20" />
There is also a specialist type of text input that is solely for email addresses. To create an email input, you simply set the type to "email". This input type has built-in validation that checks whether the input text is a valid email address. The following code snippet shows how to create an email input:
<!-- email input -->
<form action="url_to_send_form_data" method="post">
<div>
Email: <br />
<input type="email" name="email"/>
</div>
</form>
The following figure shows the output for the preceding code:
There is a type of text input that is used solely for passwords. To create a password input, you simply set the type to "password". This input type will mask the text entered by the user to hide the password text. The following code snippet shows how to create a password input:
<!-- password input -->
<form action="url_to_send_form_data" method="post">
<div>
Password: <br />
<input type="password" name="password"/>
</div>
</form>
The following figure shows the output for the preceding code:
When using checkboxes, you will give all of them a unique value for the name attribute and you will need to give each checkbox a unique value attribute, as shown in the following code:
<!-- checkboxes -->
<form action="url_to_send_form_data" method="post">
<div>
<input type="checkbox" name="color1" value="red" /> Red
</div>
<div>
<input type="checkbox" name="color2" value="green" /> Green
</div>
<div>
<input type="checkbox" name="color3" value="blue" /> Blue
</div>..
</form>
The following figure shows the output for the preceding code:
With checkboxes, you can select multiple values at a time. A common use case for checkboxes is when selecting multiple filters to search results.
When using radio buttons, you will give all of them the same value for the name attribute since there can only be one value selected. You will, however, need to give each radio button a unique value attribute, as shown in the following code snippet:
<!-- radio buttons -->
<form action="url_to_send_form_data" method="post">
<div>
<input type="radio" name="color" value="red" /> Red
</div>
<div>
<input type="radio" name="color" value="green" /> Green
</div>
<div>
<input type="radio" name="color" value="blue" /> Blue
</div>
</form>
The following figure shows the output for the preceding code:
In contrast to checkboxes, with radio buttons, the user can select only one value. A common use case for radio buttons is when selecting a delivery option when ordering online.
Now that we know how to create text inputs, checkboxes, and radio buttons, we need to look at the label element. In the previous examples, you might have noticed that we had text associated with the input fields either before or after an input element. The label element allows us to associate a piece of text with a form element and allows us to select the form element by clicking on the text. If we were to just include some text, as we did in Figure 4.1, we would lose this benefit and make our form less accessible for screen reader users since there would not be an associated label to call out when presenting a form element. The label element has an attribute called for, which we need to give the id for the element we wish to associate the label with. The following code snippet shows this in action:
<!-- text inputs with labels -->
<form action="url_to_send_form_data" method="post">
<div>
<label for="first_name">First name:</label><br />
<input type="text" name="firstname" id="first_name" />
</div>
<div>
<label for="last_name">Last name:</label><br />
<input type="text" name="lastname" id="last_name" />
</div>
</form>
The following figure shows the output for the preceding code:
Imagine you are creating a "comments" section for a community web page. You might want a user to comment on a video or a blog post. However, using a text input is not ideal for long text messages. In such scenarios, when you want to allow the user to add more than one line of text, you can use the textarea element to capture larger amounts of text. You can specify the size of the textarea with the rows and cols attributes. The following code snippet shows how to include textarea within a form:
<!-- textarea -->
<form action="url_to_send_form_data" method="post">
<div>
<label for="first_name">First name:</label><br />
<input type="text" name="firstname" id="first_name" />
</div>
<div>
<label for="last_name">Last name:</label><br />
<input type="text" name="lastname" id="last_name" />
</div>
<div>
<label for="message">Message:</label><br />
<textarea id="last_name" rows="5" cols="20"></textarea>
</div>
</form>
The following figure shows the output for the preceding code:
HTML provides us with a semantic tag to group related form elements and it is called the fieldset element. This element is mostly used with larger forms when you want to group related form elements together. You will probably have used online forms that make use of the fieldset element without realizing it. A common use case is when you have a large form with a section for personal details and a section for delivery details. Both of these sections of the form would be wrapped in a fieldset element. The following shows how we could include more than one form using fieldset:
<!-- fieldset -->
<form action="url_to_send_form_data" method="post">
<fieldset>
<div>
<label for="first_name">First name:</label><br />
<input type="text" name="firstname" id="first_name" />
</div>
<div>
<label for="last_name">Last name:</label><br />
<input type="text" name="lastname" id="last_name" />
</div>
<div>
<label for="message">Message:</label><br />
<textarea id="last_name" rows="5" cols="20"></textarea>
</div>
</fieldset>
<p>Do you like HTML?</p>
<fieldset>
<div>
<input type="radio" id="yes">
<label for="yes">Yes</label>
</div>
<div>
<input type="radio" id="no">
<label for="no">No</label>
</div>
</fieldset>
</form>
The following figure shows the output for the preceding code:
HTML provides us with the select element for creating select boxes. These are typically used when you have a long list of options and you want the user to select only one. Some common examples include lists of countries, addresses, and year of birth. Inside the select element, you provide a list of options inside of an option element. The following shows an example of how this looks in HTML:
<!-- select -->
<form action="url_to_send_form_data" method="post">
<fieldset>
<label for="countries">Country:</label><br />
<select id="countries">
<option value="england">England</option>
<option value="scotland">Scotland</option>
<option value="ireland">Ireland</option>
<option value="wales">Wales</option>
</select>
</fieldset>
</form>
The following figure shows the output for the preceding code:
By clicking on the blue arrows on the right-hand side of the select box, we will get the options displayed in the following figure:
Finally, now that we have a range of form elements we can use for building web forms, we now just need to know how to submit a form. The button element requires a type attribute that can have three different values. Firstly, the button value, which has no default behavior; the "reset" value, which, once clicked, will reset all form values; and finally, the "submit" value, which will submit the form once clicked. For this, we use the button element and give a value of "submit" in the type attribute:
<button type="submit">Submit</button>
In this exercise, we will write the HTML to create a simple web form. Our aim will be to produce the following web form:
Let's complete the exercise with the following steps:
<!DOCTYPE html>
<html>
<head>
<title>Simple form</title>
</head>
<body>
<h1>Create new account</h1>
<form action="url_to_send_form_data" method="post">
<fieldset>
<!-- your code will go here -->
</fieldset>
</form>
</body>
</html>
<fieldset>
<div>
<label for="title">Title:</label><br />
<select id="title">
<option value="Mr">Mr</option>
<option value="Mrs">Mrs</option>
<option value="Ms">Ms</option>
<option value="Miss">Miss</option>
</select>
</div>
<div>
<label for="first_name">First name:</label><br />
<input type="text" name="firstname" id="first_name" />
</div>
</fieldset>
<div>
<label for="first_name">First name:</label><br />
<input type="text" name="firstname" id="first_name" />
</div>
<div>
<label for="first_name">First name:</label><br />
<input type="text" name="firstname" id="first_name" />
</div>
<div>
<label for="last_name">Last name:</label><br />
<input type="text" name="lastname" id="last_name" />
</div>
<div>
<label for="first_name">First name:</label><br />
<input type="text" name="firstname" id="first_name" />
</div>
<div>
<label for="last_name">Last name:</label><br />
<input type="text" name="lastname" id="last_name" />
</div>
<div>
<label for="message">Message:</label><br />
<textarea id="message" rows="5" cols="20"></textarea>
</div>
<div>
<label for="first_name">First name:</label><br />
<input type="text" name="firstname" id="first_name" />
</div>
<div>
<label for="last_name">Last name:</label><br />
<input type="text" name="lastname" id="last_name" />
</div>
<div>
<label for="message">Message:</label><br />
<textarea id="last_name" rows="5" cols="20"></textarea>
</div>
<button type="submit">Submit</button>
If you now right-click on the filename in VSCode, on the left-hand side of the screen, and select open in default browser, you will see the form in your browser.
You should now have a form that looks like the following figure:
Now that we have become acquainted with the most commonly used HTML form elements, we will now look at how to style them.
In the examples in the previous section, the forms do not look very visually appealing by default, but luckily, we have the ability to improve the look and feel of our forms using CSS.
In this section, we will look at styling the following:
The first form elements we will look at styling are the label, textboxes, and textarea elements. These are probably the most common form elements and it is very straightforward to improve the look and feel of these elements with minimal code.
To style labels, you will typically just adjust the font you use and the size of the text. It is common to have the label element sit either on top of its associated form element or to the left.
For textboxes and textareas, typically, you will be interested in changing the size of these elements. It is common to remove the default border around these elements. Another common stylistic addition to textboxes and textareas is to add a placeholder attribute that provides the user with some text that helps them decide what needs to be typed into the textbox or textarea.
To illustrate an example of how to style these elements, we will start with the following markup, noting the addition of placeholder attributes:
<!-- HTML -->
<form action="url_to_send_form_data" method="post">
<div>
<label for="first_name">First name:</label><br />
<input type="text" name="firstname" id="first_name" placeholder="Your first name" />
</div>
<div>
<label for="last_name">Last name:</label><br />
<input type="text" name="lastname" id="last_name" placeholder="Your last name" />
</div>
<div>
<label for="message">Message:</label><br />
<textarea id="last_name" rows="5" cols="20" placeholder="Your message"></textarea>
</div>
</form>
/* CSS */
* {
font-family: arial,sans-serif;
}
label {
font-size: 20px;
}
div {
margin-bottom: 30px;
}
input,
textarea {
border: 0;
border-bottom: 1px solid gray;
padding: 10px 0;
width: 200px;
}
In the preceding CSS, you will notice that we have applied a font family to all text elements. We have set the label text size to 20px and added a bottom margin to the div elements so that the form elements are nicely spaced, vertically. Finally, we have removed the default border applied to the input and textarea elements, replacing it with just a border on the bottom.
With just minimal CSS, we have improved the look and feel of our form drastically, as can be seen in the following screenshot:
We will now look into styling the buttons that are used to submit a web form. Typically, you will see buttons with various different background colors and with different sizes applied when viewing websites with forms. Out of the box, the button element looks pretty ugly and so you will rarely see buttons without some CSS applied to them. The following is an example of how you could style a submit button:
<!-- HTML -->
<button type="submit">Submit</button>
/* CSS */
button {
background: #999;
border: 0;
color: white;
font-size: 12px;
height: 50px;
width: 200px;
text-transform: uppercase;
}
The preceding CSS sets a background color, removes the border that is added to buttons by default, applies some styling to the button text, and finally, sets a width and height:
The last form element we will look at for styling is the select box. Typically, these are styled with the intention of making the select box look similar to a textbox within a form. It is common for developers to add a custom styled downward-pointing arrow to the right-hand side of the select box. The following is an example of how you could style a select box:
<!-- HTML -->
<div class="select-wrapper">
<select id="countries">
<option value="england">England</option>
<option value="scotland">Scotland</option>
<option value="ireland">Ireland</option>
<option value="wales">Wales</option>
</select>
</div>
/* CSS */
select {
background: transparent;
border: 0;
border-radius: 0;
border-bottom: 1px solid gray;
box-shadow: none;
color: #666;
padding: 10px 0;
width: 200px;
-webkit-appearance: none;
}
The preceding CSS contains styling that essentially overrides what a select box looks like in the browser by default. Firstly, we need to remove the default background color, cancel the border, and apply just the bottom border. We also remove the custom box-shadow property, which is also applied to select boxes by default. Finally, to add a custom select box icon, we use the after pseudo selector to add the '< >' characters:
.select-wrapper {
position: relative;
width: 200px;
}
.select-wrapper:after {
content: '< >';
color: #666;
font-size: 14px;
top: 8px;
right: 0;
transform: rotate(90deg);
position: absolute;
Z-index: -1;
}
The following figure shows the output:
In real-world scenarios, simply formatting and styling the form appropriately is not enough. As a web user, you may encounter cases where form validation is performed before submitting a form. For example, while registering on a website, a user may accidentally submit a form before it is filled in completely or submit an incorrectly filled in form. Validation styling comes into play when you want to highlight the fact that a form is incomplete or incorrectly filled in.
You will probably have experienced form validation on web forms you have used in the past. HTML provides us with a required attribute, which we can apply to any form elements that we require input for. The required attribute plays an important role in contact forms; for example, on the Packt website's contact form (https://packt.live/35n6tvJ), you will notice that the name and email fields are required and the user cannot submit the form until a value for each is added.
This is in contrast with some form elements where the input is optional. With CSS, we can use the :valid and :invalid pseudo selectors in order to style elements based on valid or invalid form values. We will now do an exercise that will walk us through an example of validation styles in action.
In this exercise, we will develop a simple web form that contains some validation styling. Our aim will be to produce a web form like the one shown in the following figure:
Let's complete the exercise with the following steps:
<!DOCTYPE html>
<html>
<head>
<title>Validation form</title>
<style>
body {
font-family: arial, sans-serif;
}
</style>
</head>
<body>
<form action="url_to_send_form_data" method="post">
<fieldset>
<!-- your code will go here -->
</fieldset>
</form>
</body>
</html>
<fieldset>
<div>
<label for="first_name">First name:</label><br />
<input type="text" name="firstname" id="first_name" placeholder="Your first name" required />
</div>
<div>
<label for="last_name">Last name:</label><br />
<input type="text" name="lastname" id="last_name" placeholder="Your last name" required />
</div>
</fieldset>
Add the HTML for the remaining form elements. Notice that it is only the textarea element where we require the required attribute.
div {
margin-bottom: 30px;
}
fieldset {
border: 0;
padding: 30px;
}
label {
font-size: 20px;
}
input,
textarea {
border: 0;
border-bottom: 1px solid gray;
padding: 10px 0;
width: 200px;
}
With respect to the expected output as shown in the Figure 4.16, we style select as shown in the following code snippet:
select {
background: transparent;
border: 0;
border-radius: 0;
border-bottom: 1px solid gray;
box-shadow: none;
color: #666;
-webkit-appearance: none;
padding: 10px 0;
width: 200px;
}
We will use the following snippet of code to complete styling the select:
.select-wrapper {
position: relative;
width: 200px;
}
.select-wrapper:after {
content: '<>';
color: #666;
font-size: 14px;
top: 8px;
right: 0;
transform: rotate(90deg);
position: absolute;
z-index: -1;
}
For styling the button, we will use the styling as shown in the following code snippet:
button {
background: #999;
border: 0;
color: white;
font-size: 12px;
height: 50px;
width: 200px;
text-transform: uppercase;
}
input:valid,
textarea:valid {
border-bottom-color: green;
}
input:invalid,
textarea:invalid {
border-bottom-color: red;
}
If you now right-click on the filename in VSCode, on the left-hand side of the screen, and select open in default browser, you will see the form in your browser. When you try to submit an incomplete form that has validation in it, the form will not submit and you will see something like the following screenshot:
From the video store product page examples from the previous chapter, where we built a whole web page, component by component, we will now build two complex forms for the video store project in order to put our new knowledge into practice.
In this exercise, we will write the HTML and CSS to create an account signup form. Our aim will be to produce a web form like the following wireframe:
Let's complete the exercise with the following steps:
<!DOCTYPE html>
<html>
<head>
<title>Signup form</title>
<style>
body {
font-family: arial, sans-serif;
}
</style>
</head>
<body>
<h1>Create new account</h1>
<form action="url_to_send_form_data" method="post">
<fieldset>
</fieldset>
</form>
</body>
</html>
<fieldset>
<div>
<label for="first_name">First name: <span>*</span></label>
<input id="first_name" type="text" name="firstname" required />
</div>
<div>
<label for="last_name">Last name: <span>*</span></label>
<input id="last_name" type="text" name="lastname" required />
</div>
</fieldset>
<fieldset>
<div>
<label for="first_name">First name: <span>*</span></label>
<input id="first_name" type="text" name="firstname" required />
</div>
<div>
<label for="last_name">Last name: <span>*</span></label>
<input id="last_name" type="text" name="lastname" required />
</div>
<div class="checkbox">
<input id="newsletter" type="checkbox" name="newsletter" value="yes" />
<label for="newsletter">Sign up for newsletter</label>
</div>
</fieldset>
<div class="checkbox">
<input id="newsletter" type="checkbox" name="newsletter" value="yes" />
<label for="newsletter">Sign up for newsletter</label>
</div>
<div>
<label for="email">Email: <span>*</span></label>
<input id="email" type="email" name="email" required />
</div>
<div>
<label for="password">Password: <span>*</span></label>
<input id="password" type="password" name="password" required />
</div>
<button type="submit">Create new account</button>
fieldset {
border: 0;
}
fieldset>div {
margin-bottom: 30px;
}
label {
display: block;
margin-bottom: 10px;
}
label span {
color: red;
}
input {
padding: 10px;
width: 200px;
}
input:valid {
border: 2px solid green;
}
input:invalid {
border: 2px solid red;
}
.checkbox input {
float: left;
margin-right: 10px;
width: auto;
}
button {
background: green;
border: 0;
color: white;
width: 224px;
padding: 10px;
text-transform: uppercase;
}
If you now right-click on the filename in VSCode, on the left-hand side of the screen, and select open in default browser, you will see the form in your browser.
You should now have a form that looks like the following figure:
We have now completed the signup form for our video store. We will also need to create a checkout page to allow the user to complete their online purchases. The next exercise will show how you can create a checkout form.
In this exercise, we will write the HTML and CSS to create a checkout form. We will make use of all the concepts and form elements we have learned about in the chapter. Our aim will be to produce a form similar to the following figure:
Let's complete the exercise with the following steps:
<!DOCTYPE html>
<html>
<head>
<title>Checkout form</title>
<style>
body {
font-family: arial, sans-serif;
}
</style>
</head>
<body>
<h1>Checkout</h1>
<form action="url_to_send_form_data" method="post">
<fieldset>
</fieldset>
</form>
</body>
</html>
<h2>Shipping address</h2>
<div class="double-input">
<div>
<label for="first_name">First name: <span>*</span></label>
<input id="first_name" type="text" name="firstname" required />
</div>
<div>
<label for="last_name">Last name: <span>*</span></label>
<input id="last_name" type="text" name="lastname" required />
</div>
</div>
<div class="single-input">
<label for="address">Address: <span>*</span></label>
<input id="address" type="text" name="address" required />
</div>
<div class="double-input">
<div>
<label for="postcode">Postcode: <span>*</span></label>
<input id="postcode" type="text" name="postcode" required />
</div>
<div>
<label for="country">Country:</label>
<div class="select-wrapper">
<select id="country">
<option value="england">England</option>
<option value="scotland">Scotland</option>
<option value="ireland">Ireland</option>
<option value="wales">Wales</option>
</select>
</div>
</div>
</div>
<h2>Shipping method</h2>
<div class="checkbox">
<input id="standard" type="radio" name="shipping-method" value="standard" />
<label for="standard">Standard</label>
</div>
<div class="checkbox">
<input id="nextday" type="radio" name="shipping-method" value="nextday" />
<label for="nextday">Next day</label>
</div>
<button type="submit">Submit</button>
fieldset {
border: 0;
padding: 0;
}
fieldset > div {
margin-bottom: 30px;
}
label {
display: block;
margin-bottom: 10px;
}
label span {
color: red;
}
Notice that the input and select have same style as shown in the following code:
input,
select {
border: 1px solid gray;
padding: 10px;
width: 200px;
}
select {
background: transparent;
border-radius: 0;
box-shadow: none;
color: #666;
-webkit-appearance: none;
width: 100%;
}
.select-wrapper {
position: relative;
width: 222px;
}
.select-wrapper:after {
content: '< >';
color: #666;
font-size: 14px;
top: 8px;
right: 0;
transform: rotate(90deg);
position: absolute;
z-index: -1;
}
.single-input input {
width: 439px;
}
.double-input {
display: flex;
}
.double-input > div {
margin-right: 15px;
}
.checkbox input {
float: left;
width: auto;
margin-right: 10px;
}
button {
background: green;
border: 0;
color: white;
width: 224px;
padding: 10px;
text-transform: uppercase;
}
input:valid {
border: 2px solid green;
}
input:invalid {
border: 2px solid red;
}
If you now right-click on the filename in VSCode, on the left-hand side of the screen, and select open in default browser, you will see the form in your browser.
You should now have a form that looks like the following figure:
An international online property website has approached you to design a search form for their listings page. This form should have the following fields: search radius, price range, bedrooms, property type, and added to the site, and an option to include sold properties in the user's search. Create your own solution using the skills you have learned in this chapter:
Note
The solution for this activity can be found in page 588.
In this chapter, we continued our journey into building web pages by exploring web forms. We first studied the most common form-based HTML elements, including inputs, select boxes, textareas, and buttons. We then looked at the most common styling methods for styling forms. To put this new knowledge into practice, we then built different forms.
We took some time to understand when you should use checkboxes and when to use radio buttons. We also spent some time looking at how you can add validation styles for web forms.
In the next chapter of this book, we will learn how to take our web pages to the next level. We will learn how to make our web pages even more appealing by creating and adding themes to our web pages.