Lab 02: Creating an HTML Form¶
This lab activity explores some more features including those in HTML forms and intermediate CSS. We will attempt to create a Student Record Form in HTML utilizing these features (minus information retrieval, this will be covered when we go through PHP).
We will attempt to recreate a form resembling the one as shown below:

Note
Right-cick on the image and select "Open Image in New Tab" to have a clearer view of the image.
General Requirements¶
If you'd like to take a crack at this on your own, here are some requirements to satisfy. Otherwise, skip over to #getting-started to follow through.
Image Assets¶
For this activity, you will require some image assets to work with. Download them HERE.
External Font¶
The font used to create this form is called Urbanist, and it can be found in Google Fonts. Click HERE to open the Google Fonts page showcasing the font and to get details on incorporating it into your web form.
Project Folder Structure¶
It is suggested that you follow this project folder structure. Just in case you do not, though, ensure that the proper modifications are made.
Dropdown Inputs¶
For Status under Personal Particulars, include the following in the drop-down list:
- Please select status (disabled, selected)
- Active
- Deferred
- Graduated
- Terminated
For Enrolled Program under Academic Record, include the following:
- Please select a program (disabled, selected)
- Foundation in Computing (FIC)
- Diploma in Information Technology (DIT)
Form Submission¶
Upon selecting the Submit button, redirect it to a different webpage called form-submitted.html.
In this page, create a webpage that essentially lets the website visitor know that the details entered into the form have been successfully collected.
Include any other element/text/etc. that can be considered relevant here.
Extra Task¶
Consider someone who may open your form on a mobile device such as a smartphone or tablet.
Web developers or designers make use of the following meta tag in the <head> section:
This will set the viewport of the webpage, which will give the browser instructions on how to control the page's dimensions and scaling.
Apart from that, media queries were used to cater for different screen sizes. Look up media queries online and try to incorporate it into your web form. You may use your browser's inspector tool to simulate viewing the webpage from a mobile device of your own choosing.
Getting Started¶
Let's begin.
Initial Setup¶
Start with the typical HTML boilerplate code.
If you're using VSCode, you may use this shortcut: type html and select html:5 in the dropdown menu that appears (selecting just html is fine too, but I think you'll need to populate it a little bit more).
It should then produce the following boilerplate code (along with some changes):
| index.html | |
|---|---|
- Set the
<title>attribute value to"Student Record Form".
Apart from this, we will start with an empty main.css file.
Video Walkthrough¶
If you would like a step-by-step walkthrough to complete this form, you may view it below. I have placed several timestamps to mark down a few steps to producing this HTML form.
Otherwise, you may follow the steps laid out in the next section. The steps follow the order in which I took to create this form as per in the video walkthrough.
Steps¶
Font Implementation¶
From the Google Font page containing the Urbanist font, click on Get Embed Code.
Select the @import radio button in the "Web" tab, and copy the import statement.
Do not include the <style> tags, this will cause errors otherwise since it's not CSS syntax.

Paste that @import statement as the first line in main.css, followed by specifying it as the font to use throughout the webpage.
Form Element¶
Back in index.html, let's add in a <form> element inside the <body> section.
For our student record form, this will be considered the parent element containing all structural aspects of the form.
Ensure that the action and method attributes are entered correctly.
The method value being post over get is not important now, but it's important later on once we implement information retrieval in a subsequent lab activity.
| Form Element | |
|---|---|
Letterhead Logo¶
Inside the <header> section created inside the <form> element, insert the letterhead logo logo.png and an <h1> element with text "Student Record Form".
Set the alt attribute of the <img> element created as "Taylor's Logo".
I happen to keep all the images in this project in a subfolder called images, so I will reference that in the <img> element's src attribute.
You'll want to place in an appropriate path to logo.png as appropriate, more appropriately at least within your project folder.
| Letterhead Logo Header | |
|---|---|
Adding the "center" class inside the <header> element, as well as the ID #top-title to this same element allows us to target it with new CSS styling.
We will use the "center" class to specify that for each container element that has this class, all the text will be centered.
You should now see that the contents in the <header> element are properly centered, proper for the letterhead in our web form.
Personal Particulars¶
A <fieldset> element tends to go along with a child <legend> attribute.
Inside this <legend> attribute, rather than just inserting the text "Personal Particulars" directly, let's place it as an <h2> element instead.
This is merely just to make it stand out a little bit - you can get by with other ways like using <p> or <span> elements, but that may require a different set of CSS styling altogether.
| Personal Particulars Fieldset | |
|---|---|
The .container class given to this fieldset (including the other fieldsets in this form) borrows from how we have a container class readily available in CSS frameworks like Bootstrap or Tailwind CSS.
While we're not necessarily going to create something that's as complex, this is a nice reusable class we can use for various visual aspects of our webpage.
We will set our .container style as follows:
Back in the HTML code, let's structure our textfields.
We will introduce a section.row element;
borrowing again from Bootstrap and Tailwind CSS, the .row class, this will enable us to use .column-x classes to prepare a visually clean column layout on wider screens (such as on laptops and desktops) and return to a single layout in narrower screens (such as on mobile devices).
We should structure our HTML first before getting to styling them in CSS - realistically I believe it's better than speculating what styles should be present before including the scaffolding in our code.
We house the required textfields inside each of the section.column-50 elements accordingly.
(The naming convention column-50 (generally, column-x where x is an integer) indicates 50% of the browser window's width.)
Row 1: First Name, Last Name¶
For each of the textfields (First Name and Last Name), we will keep their respective name and id attribute values the same.
Including an id value will help especially when involving JavaScript code, whilst name is important for PHP later on.
The required attribute will ensure that the textfield is filled up first before form submission is allowed, while autofocus makes it so that specific textfield which has this attribute will be focused on as soon as the page loads (you can see this textfield highlighted upon the page being fully loaded).
By this point, you should see that without placing in the CSS styling, the arrangement of these two textfields do not match. It's fine, let's carry on with the rest of the HTML code in this fieldset first.
Row 2: Student ID, Status¶
Let's create another section.row element with two more section.column-50 child elements again, this time for the Student ID and Status.
- For the Student ID textfield, we make use of a
patternattribute, which generally takes in a regular expression (regex) value that will restrict what string inputs are accepted. You can generate regular expressions you require easily here. Learn more about them here. (Try to figure out what kinds of input string patterns are allowed based on the used regex used.) - Status input will be in the form of a dropdown input list using the
<select>, where users get to choose any of the given options (each as its own<option>element). For each<option>element, avalueattribute is expected. Theselectedattribute makes it so that this<option>is pre-selected immediately once the webpage is fully loaded. We can also use thedisabledattribute to prevent anyone from selecting this option (greyed out, similar to a disabled checkbox or radio button).
Row 3: Address¶
Continuing on, we create yet another section.row element, just to contain the Address textfield.
Row 4: Contact Number and Email¶
One more section.row element, now for Contact Number and Email textfields.
Note that we also have an email input type value, instead of needing to craft a new regex for that.
You could do it this way, though, supposing you only allow specific emails to be entered in, for instance.
Good job, we just completed our first fieldset! Now, moving forward to the next fieldset...
Academic Record¶
In the same fashion, we will craft out the fieldset.container#academic-record element like as follows first:
| Academic Record Fieldset | |
|---|---|
There are at least three different inputs in here: Enrolled Program, Semester Intake, and a table containing a CGPA value.
- The Enrolled Program input is yet another
<select>element:select.programme#programme - Semester Intake is selected from one of several options arranged as radio buttons:
section.radiogroup#intake - CGPA is calculated using several textfields arranged in a table structure:
table.cgpa-table
With radio inputs, it is critical that the name of all the related radio buttons are the same; otherwise, it will be possible to select multiple radio button options at once.
Additionally, this will cause incorrect collection of data on the PHP side when the form is submitted.
In our case, we will give the name value of "intake".
With input.cgpa#cgpa, we give the type value of number, denote a value range of \([0,4]\), and a default value of 0.00.
Additionally, we make this readonly; the value can dynamically change with some JavaScript code embedded into it.
Academic Progression¶
As like with the previous two fieldsets, we will craft out the fieldset.container#academic-progression element like as follows first:
| Academic Progression Fieldset | |
|---|---|
Inside it are going to be a series of checkbox inputs denoting "Prospective Degree Options", and a textarea for "Remarks".
Unlike radio button inputs, you may choose to give each checkbox name a different value.
Additionally, with <textarea> inputs, you may specify the cols and rows attribute values to automatically resize them to a specific set of dimensions when the page is loaded.
If anything, we can leave it be and allow users to resize it if needed (to disable this, set the resize property of this <textarea> element to false).
Submit and Reset Buttons¶
Create a section.center.container#actions element after all the <fieldset> elements.
Include the submit and reset inputs (indicate the correct type values resectively) inside them.
This section should be automatically centered since we are including the .center class in it.
| Actions Section Element | |
|---|---|
The Rest of the CSS Styles¶
At this point, we have finished structuring our HTML webpage. Now to polish it up properly with some CSS styles. As you go along, provided your machine's screen resolution is big enough, I encourage you to have your code editor on one side and the browser on the other so that you can view the changes each time you save progress on your stylesheet.
Global Custom CSS Properties¶
To start off, we are going to declare some global custom properties to use throughout the stylesheet.
These property values are arbitrarily chosen when I crafted this form, but you may choose to modify them as you see fit to produce your own variation of the web form.
We will keep this in :root.
<body> Element and The Background Image¶
Now, we get to implement styles on the elements itself before targeting the element id and name values.
Let's start with the body element - this is we get to implement the background image.
background-image: specify the image to use as the webpage's background, typically usingurl()background-size: used here to ensure the background image covers all visible area within the browser windowbackground-position: used here to center the background imagebackground-repeat: set tono-repeatto ensure no repeated instances of the background (though since it's covering the whole browser window, this may not be necessary)
Additionally, I have included in a border value to produce a maroon border around the webpage, and a margin value of 0 to remove any default margin introduced.
By default, the visible content's height is strictly relative to how much is contained in the webpage - this means that on a ridiculously large screen resolution (let's say something like 5K or more), there's a high chance you'll see an empty white (or black?) area at the bottom of the browser window.
To mitigate this and ensure the background image definitely does cover the whole browser window, we set the min-height value to 100vh (vh stands for visible height).
Slow Image Loading and The WEBP Image Format
If you find that the background image (and/or the logo on top) loads slowly, it could be any or all of these factors: the size of the image and the speed of your internet connection. Whilst we can't dictate how fast everyone's internet connection is supposed to be, we can definitely reduce this tendency of slow-loading images by using WEBP images instead. These are image file types that are more well-suited for use on a website due to their relatively smaller size.
PNG files tend to be much larger but have a higher image quality to them, whilst JPG/JPEG files can be small too but not of the same high quality. WEBP files are in the same boat as JPG/JPEG files too, as I have also frequently noticed a drop in image quality when converting them. If you'd like to use the same Terminal WEBP image converter I currently use (i.e., cwebp from Google), you can learn more about it from here.
<form> Element¶
You may notice that the form's text is not as visible anymore with the strong colors of the background image.
Let's now modify the form element to mitigate that while styling it.
-
We place a background color overlay on the background image by specifying a background color for the
formelement.rgb(255, 255, 255)is the same as a white background, but what's special about usingrgba()is that we get to specify the opacity of the color as a 4th argument. This effectively means thatrgba(255, 255, 255, 0.8)produces a translucent white color with 80% opacity. There are also other ways to introduce transparency to the background, but for our intents and purposes, this is a much simpler solution than some of those other solutions you can find from online. -
We also add in a top and bottom padding of
2remto ensure there is a cushion of space on top and at the bottom of the form. We leave the left and right paddings at0.
The Rest of The Elements¶
For the rest of the elements, these are the styles I implemented:
Notice that I made use of the custom properties defined earlier in :root.
Like regular variables, this will reduce the need to search out for individual values (and possibly missing them, human error) by keeping it to a specific portion of the CSS stylesheet that's easy to find and modify at once.
For the table element, I set the border-collapse property to collapse to remove any padding between the table cells, its width to full, and each tr, th and td element to use a solid thin (1px) border of the same color as the one implemented on the body element.
Notice that we did not target the input elements yet - that will come later.
For now, let's target the class and id values.
Rows in The First Fieldset¶
We first set up the .row dynamic with the following:
Radio Buttons¶
For the radio buttons, we modify their font sizes and top margins:
Letterhead Logo Image¶
We can set the letterhead logo image size to scale to 40% of the visible width of the browser window (i.e., 40vw, where vw stands for visible width), but subject to a maximum width of 600px.
Action Buttons¶
Nothing much, we add in a simple top margin here to section#actions.
CGPA Table¶
Here, we set the table width to 75%, vertical margin (top and bottom) to 1.5rem and position it in the center with horizontal margin (left and right) to auto.
Additionally, we set the following styles to its child elements:
th: set width to75%td: align text and inline elements to thecenterinput[type="number"]: set width to75%, vertical margin to.25remand horizontal margin toautotfootcontents: align text and inline elements to theright
Fieldsets¶
We have now commenced modifying the style of the inputs in this form.
Now to target those in the fieldset elements..
Responsive Design - Columns¶
At this point, you should see that all the input fields inside the fieldsets are in full width - this is to be expected on a narrower screen resolution.
In a wider screen resolution as one may find with desktops and laptops, for instance, you may want to make better use of the space by implementing columns.
This is where we now use media queries to target the .column-50 class elements, among some other elements as well.
Let's set the column arrangement to take into effect for screens that are at least 768px wide.
At the very end, you should now have replicated the webpage as shown earlier in this lab activity.. huzzah!! There's still one more thing to do, though - create an acknowledgment page for when the form is submitted.
"Form Submitted" Acknowledgment Page¶
This is going to be a sort-of scrappy acknowledgment page... with some styling, at least.
We will name this new HTML file form-submitted.html (following where we created our <form> element earlier).
Inside a typical HTML document structure, contain the following in the <body> section:
| form-submitted.html | |
|---|---|
Include a <link> element in the <head> section to an external CSS stylesheet with the following contents:
| form-submitted.css | |
|---|---|
You should now see this as your acknowledgment page:
Complete HTML and CSS Code¶
I implore you to try this activity as much as you can - the steps should be enough to guide you through completing it. However, you may choose to refer to the complete code if you'd like to check if you did anything wrong (assuming it happens.. don't worry, this is normal!). But if you made it this far either on your own or using the guide/steps given above, give yourself a pat on the back! This wasn't easy, but I sure hope this taught you a lot about creating this kind of form from scratch! 😊
Form HTML and Stylesheet
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | |
main.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | |