Kunal
Frontend Shortcut
Published in
18 min readNov 18, 2017

--

You are on a Train returning from your office. There is no one else in the coach, but as soon as you turn your head, Professor Dumbledore appears out of nowhere in the seat next to you! Your mind goes — what the hell.. what the hell… what the hell… and he interrupts your panic. In his wise voice, he asks you: “I am planning to take Hogwarts online, can you build our Admission Form in HTML?”

What will you do?

Of course, you will accept the gig, won’t you? Moreover, you might get a free admission to Hogwarts after this gig, right?

So, let’s get to work and complete the task given by Dumbledore.

Before disappearing from the train, Dumbledore gave you a list of information that a candidate must fill in the Admission Form:

  • Name
  • Is any of the Parent a Muggle
  • Which element you naturally attract to: air, water, or fire? (a candidate may be attracted to more than one element)
  • Which is your favorite House at Hogwarts?

Along with the list, Dumbledore also gave you an image of Hogwarts to use:

[Note: This is the second tutorial in the series of Beginner HTML & CSS tutorials at Frontend Shortcut. If you have never coded anything in HTML and CSS before, then I would recommend reading the first tutorial here, before diving into this post]

The Background Image

Let’s start by adding the image that Dumbledore gave us as the background of our web page.

To set the given image as entire page’s background we will create a “div” and set its width and height to cover the entire page, and set then the image as its background image using “background-image” property.

Create a file named admission.html with following content:

If you have read the first post in the series then you already know what the above code does.

Create a new folder named “images” in your current directory (folder). Download and copy this image into the folder and name it “hogwarts.jpg”.

Come back to your project directory (where you put your admission.html file), and create a file named “style.css” with following content:

Notice how I selected “html” and body” tag in our CSS. From the previous tutorial, we know that we can select an id using “#” prefix, like this:”#id-name”, and a class using “.” prefix, like this:”.class-name”. To select a tag we just write the tag name, without prefixing it with anything. So, to select the “body” tag we write: body{...}, and if you want to select more than one element or tag then simply separate them with a comma, like this: html, body{...}.

Next, we are setting the height of html and body to 100%. Why? Because by default every element has 0 height if there is no content inside them. But we want our div named “hogwarts-background” to cover the entire screen, right? To do that, its parent elements must cover the screen first.**

What the hell is parent element?

Parent Element

See, our <body>...</body> resides inside <html></html>, right? So, html is parent element of body. Next, our “hogwarts-background” div: <div id="hogwarts-background">...</div>,resides inside <body>...</body>, so, body is parent of that div.

height:100%

Now, to make our div cover the entire screen, we need to make its parents, “html” and “body”, cover entire screen first. Setting “height:100%” means: cover the entire height of the parent element. So, if a parent element’s height is 500px and we give its child element height:100% then the child’s height will be 500px (100% of 500 = 500).

Why aren’t we setting “width” to 100% then, why only height? Because “div”, “html” and “body”, these elements already have default width of 100%.

url(…)

The second thing you will notice is url(...). This is how you include any external resource (generally images and fonts) inside CSS, just provide the path of the resource (image in our case) inside parentheses.

The path “images/hogwarts.jpg” means: there is a directory named “images” in the current directory (the directory where the style.css file resides), inside that “images” directory is a file named “hogwarts.jpg”.

Note, there is not “/” at beginning of the path. If you put “/” before the path, like this: “/images/hogwarts.jpg”, then it will try to find the image inside your system’s root directory, not your current directory. So, be careful with that.

Margin

If you open your admission.html in your browser now, you will see a strange white “gap” around your screen. The background is not fitting the screen at the edges.

This may or may not happen to you depending on your browser. Some browsers set a “margin” by default on the body element.

What the hell is margin?

The margin is like personal space of HTML elements. If you set an element’s margin to 20px, it will place itself 20px away from all its adjacent elements (including the parent element).

That’s why our hogwarts-background div has some gap along the edges, the body element has some margin by default. Let’s set it to 0px:

html, body{
height: 100%;
margin: 0px;
}

Background-size

After solving the margin issue, we have one more problem to solve. Do you see an awkward bar at the bottom?

This will happen if your screen size is greater than your image size. The background image won’t get scaled up by automatically.

When you set an image as the background of an element using background-image property, one of the two things can happen:

  • Size of background image is less than size of element: In this case, the image will be repeated until it fills the element. The image won’t stretch automatically. This is happening in our case.
  • Size of background image is greater than size of element: In this case, you will see only a portion of the image that the element’s size can cover. The image won’t scale down automatically.

These are undesired situations for our purpose. We can turn off the image repetition by “background-repeat” property, and we can use “background-size” property to scale the background image to fit the element.

Let’s do it:

Here we set “background-repeat” property to “no-repeat”, you can set it to “repeat-x” to repeat the image in the x-direction, or you can set it to “repeat-y” to repeat the image in the y-direction. We don’t want repetition in any direction, so we set it to “no-repeat”.

In the value of “background-size” property, the first 100% is for width, and the second 100% is for the height. Now width and height of the background image will scale up and down as per the width and height of the element.

However, there is one problem with setting the background-size 100%. It scales without maintaining the aspect ratio of the image. Our image has more width than height, like a desktop wallpaper image. That’s why it looks good on desktop monitors. But if you view the same image on a Mobile phone then it will look horizontally compressed. To see this simply resize your browser to shape of a mobile phone and see the difference.

We don’t want this. We want to display only the portion of the background image that fits the screen, instead of squeezing the entire image in the container.

To do this, we can set the background-size property to “cover”. The “cover” does exactly what we need. If the element is bigger than the image it will scale up the image keeping its aspect ratio same, and if the element is smaller than the image then display only the portion of the image that fits the element, keeping the aspect ratio of the image same.

Let’s update the background-size property to “cover”:

#hogwarts-background{
display: flex;
align-items: center;
width: 100%;
height: 100%;
background-image: url("images/hogwarts.jpg");
background-repeat: no-repeat;
background-size: cover;
}

On resizing the browser window now you will notice that the image doesn’t distort. But the image is not in the center. To set it to center, use: background-position: center.

Before moving forward, pat your back, my friend, you’ve learned all the commonly used “background” properties in CSS. There are more, but these are the most commonly used ones. :)

Transparent Black Box

Now, let’s create a transparent black box in the center of the screen on which we will put our admission form. So, go ahead and update your html file:

and our style.css file:

You will notice a number of new things here:

max-width: We are setting the “width” property to 90%, BUT we do not want it to be wider than 500px. We are setting this upper limit because we do not want this box to go too wide on wide screens. We are doing this because we want to cover 90% of screen area when viewing on mobile device, but we do not want to cover 90% width on bigger screens, so we set a max limit on width using max-width property.

rgba(0, 0, 0, 0.6): Till now we have given the divs background color by their name, like green, black, red. But HTML has a limited number of color names. To get finer control over colors we use rgba notation. rgba stands for Red Green Blue Alpha. Every visible color can be decomposed into its Red, Green and Blue components. Alpha is for transparency, it ranges from 0 to 1. By setting it to 0.6 we are keeping 40% transparency. So, “rgba(0,0,0,0.6)” means a 40% transparent black color.

As you can see, the black-box is not at center. Let’s center it horizontally first.

We saw that we can define personal space of an element by using “margin”. What if we could set the left side margin and right side margin to an equal number? Our div will be centered horizontally. There is a value that can do this: auto. We can set “margin-left” and “margin-right” to “auto” and it horizontally centers our div.

Let’s do it:

#form-wrapper{
width:90%;
max-width: 500px;
height: 500px;
margin:0px auto;
background-color: rgba(0,0,0,0.6);
}

Okay, we added the margin, but this syntax is different than our previous use of margin, isn’t it?

We have two values for margin: “0px” and “auto”, separating both with a white space. When giving margin this way, the first value is set to “top” and “bottom” and the second value is set to “left” and “right “of the property. So, writing margin:0px auto is equivalent to writing:

margin-top: 0px;
margin-right: auto;
margin-bottom: 0px;
margin-left: auto;

Great, our box is centered on the x-axis. Now, let’s center it in the y-axis, i.e., vertically. If you are with me till now, you will think: simple, let’s set margin-top and margin-bottom to auto as well.

Sorry to break your heart, that won’t work. It doesn’t work because the value of “auto” for margin-top and margin-bottom is 0 for div elements by default.

There is a good news though. In 2011 CSS introduced a new display property named “flex”. All the divs have a “display” property that is set to “block” by default. If you change that “display” property to “flex”, then you get tons of new features which previously div elements didn’t have. One of those functionalities is aligning inner elements in the centre vertically using margin-top and margin-bottom auto.

Let’s do this:

You will notice, we added display: flex to “hogwarts-background” div and set margin of all sides of “form-wrapper” element using margin: auto. Our black-box is at the centre now.

HTML Form

Now that our black-box is ready, we will create the admission form inside it. We create forms in HTML using form tag: <form>...</form>. We also know the 4 inputs we have to take from a candidate, and the first one is candidate's name. We get inputs from a user using an input tag: <input>. "input" is a self-closing tag, just like the "link" tag, so we don't need to write </input>.

Let’s create a form and put an input element to get candidate’s name:

Okay, let’s go through the number of new things that we encountered here:

input: as we discussed, it’s used to get input from the user

type: We can take input from users in a number of forms, like checkboxes, radio buttons, submit buttons, and more. Since we need candidate’s name here we keep the type text.

name: All the data a user enters in your HTML form, eventually gets submitted to a server. The server identifies the data with this “name “property. I keep “id” and “name” properties same.

label: Only displaying an input box is totally valid, but how would a user know that she has to type her name in that box? So, labels generally accompany inputs, and we let the user know what to type in the input. Here we display: “Your name:”.

for: Normally a form will have more than one inputs and more than on labels. So we use “for” attribute of the label to identify which input it is related to. Put the id of the related input element in the “for” attribute of the corresponding label.

If you open your file in the browser, you will notice that the text in the label is not really looking clear on the black background. Let’s set the color of all the text inside the form to “white” using the “color” property.

And update our styles a bit:

Our first element of the form is ready! How does it look?

Ugly!

It looks ugly because the input and label stick on the top-left corner of the black-box. Why is that? In HTML, coordinates starts from top-left corner — that is (0,0) of our screen as per HTML. So, by default, all the elements will starts from their parent’s top-left corner, until explicitly mentioned.

Padding

Remember “margin”? What if we simply give some margin to the input and label element?

We can do that, but there is a little problem though — you will have to give margin to all the elements. But there is a convenient way of solving our problem here — give some padding to the black-box.

If the margin is the space an element keeps from other elements, then padding is the space an element keeps from its child elements. If we set padding of 20px to an element, then all its child elements will keep 20px distance from the border of that element.

Let’s update our code, the concept will get clear once you see the result:

#form-wrapper > form{
color:white;
padding: 40px;
}

Better.

Now let’s move to our next requirement — Is any of the Parent a Muggle? This question has only two possible answers — “yes” or “no”. In this kind of scenario, we use Radio Buttons.

Radio Buttons

We use radio buttons when we want the user to select only one of the given options. Let’s update our admission.html:

You will see a couple of new things here:

<br>: this element inserts a line break (carriage return), or new line, as many call it. Two consecutive <br> will produce two line breaks. If we don’t write <br>, all the elements will display in a single line, which we don’t want. Give it a try, remove all the “<br>” and notice the difference.

type=”radio”: we used type=”text” to get text input from user, similarly to create a radio button, we use type=”radio”

name: One thing to keep in mind in case of radio buttons is that all the radio buttons which belong to the same group, have a same “name”. That’s how the browser knows that only one of these radio buttons is allowed to be selected. If you are able to select more than one radio button, then make sure you are using a same name for the inputs.

value: All the data entered by a candidate will eventually go to a server. The actual data that goes to server from the selected radio button is the data inside its “value” attribute. So, if you keep everything same but change “value” attribute of the first radio button to “Hell Yea!”, then the candidate will still be displayed “Yes” (as per the <label>), but the actual data that will go to the server will be “Hell Yea!”.

Block and Inline elements

At this point, your mind might be having this uncomfortable question. When we create divs they automatically stack one over the other, we don’t need to use <br>, then why the input elements, labels, and the text “Is any of the parent Muggle?”, these don’t stack one over the other, why they align horizontally?

The reason is, <div> is a block element, while <input>, <label>, and normal text inside HTML are by default inline elements. Block elements don’t let any other element to sit beside them, any new element has to start below that element. Inline occupy only the amount of width that is needed by its content and allow other elements sit beside it.

Fonts

Now, while you are making this awesome form, Dumbledore comes to see your progress; and of course, he magically appears beside you out of nowhere. He looks disappointed.

What! That was insulting! We ain’t taking insult from any one man. Let’s make our form look more magical. The best way to do that is to use some magical Font for our text.

We use the “font-family” property to change our font. Suppose if you want to use “Times New Roman” font, then you simply put this in your CSS: font-family: "Times New Roman", or if you want to use Arial simply write: font-family: "Arial".

However, we do not want to use any normal font here. We need some magical looking font. Luckily, Google provides some free fonts that you can use at https://fonts.google.com/. We will use this specific font: https://fonts.google.com/specimen/Jolly+Lodger.

Once you select a font from Google fonts, Google will give you two codes: one <link> element which is used to load the font from Google's server, and the font's name that we can set in font-family property. Let's put the <link> element in our HTML:

Great, the font family is included and we can use it now, let’s update our CSS:

Okay, a couple of new things here:

font-family: We set font-family to “Jolly Lodger”, the name of the font that is loaded in HTML by <link> element.

font-size: Most of the browser has a default font size of 14px. You can change this by updating the font-size property of any element. In our case the default font size was too small, so I increased the font-size of elements inside our form.

letter-spacing: Letter spacing is the gap between the characters in the text. The new font that we are using has a very narrow gap between the characters, so I manually increased it to 1px.

#form-wrapper > form > input: This selector means: select all <input> elements inside the <form> element that is in turn inside an element whose id is “form-wrapper”.

It looks magical, doesn’t it?

Now let’s add new our next requirement that Dumbledore gave us:

“Which element you naturally attract to air, water, or fire(a candidate may choose more than one element)?”

Checkboxes.

Just like the case of Radio buttons, here also we have a limited number of answers that a user can select from. There is one important distinction though, in this particular case a candidate is allowed to select more than one displayed option.

In the scenarios where we know the answers are limited and want to allow the user to select more than one option, then we use checkbox.

Let’s do this:

type=”checkbox”: We set the “type” attribute of an input element to “checkbox” to display a checkbox.

value: Same as the radio button, the data inside the “value” attribute of a checkbox actually gets submitted to the server.

That looks great!

Now we have the last requirement to be filled by the wannabe wizards: Their favourite House.

BTW which one is your favourite? Mine is Slytherin.

As you already know, we have four houses in Hogwarts, and the candidate has to select his favourite one. If you are thinking that we can use a radio button for this, then you are absolutely right! We have a limited number of options and user is allowed to select only one, so radio button is perfect for this.

But, I will show you one more way of dealing with this kind of situation. We will use a <select> element for this requirement. You might know this element as “drop-down”.

Let’s implement it in our code:

Let’s look at the new stuff here:

<select>: We use the select tag to display a drop-down.

name: Note that we give the name to the “select” tag, not to the options inside it.

<option>: Put the individual options that you want to display in your dropdown inside “<option>” elements.

Also, let’s include “select” element along with “input” element to give it font-family and font size. So the last block of your CSS will become:

#form-wrapper > form > input, select{
font-family: 'Jolly Lodger';
font-size: 22px;
letter-spacing: 1px;
}

#form-wrapper > form > input, select: this selector means select all the <input> and <select> elements inside <form> element, which is inside an element whose id is "form-wrapper".

Great! We are almost done here.

The last thing we need is a Submit button that can submit the form. We can create normal buttons using <input type="button"> in HTML. But we won’t use that here, we will use <input type="submit"> instead. They both will display a button, but the submit button has one additional functionality: when we click on a submit type button, it will automatically send our data to the server.

So, here is what our HTML looks like now:

value: The “value” attribute of the buttons play a different role than the value attribute for checkboxes and radio buttons. The “value” attribute of a button is used to display the text on the Button, which in our case is: “Submit”. Try changing it to see the difference.

Let’s see what result do we get:

Oh no! Our Submit button went outside the Black box!

Why?

We have set our black-box’s height to 500px, but now our content has gone longer than 500px and needs more space than, so it overflows out of our black-box.

How to deal with this situation?

min-height:

We will use “min-height” in place of “height” to set the minimum height of 500px, it can be longer than 500px but not smaller than that;

After updating, our form-wrapper styles look like this now:

#form-wrapper{
width:90%;
max-width: 500px;
min-height: 500px;
margin:auto;
background-color: rgba(0,0,0,0.6);
}

That should fix our issue. Let’s give our form a little finishing touch. Here’s our final CSS in style.css:

form-wrapper > form > input[type=”submit”]: This is how we select an input element with specific type (“submit”, in our case). We used this selector because we want to give some specific styles to the submit button which are different from other input elements.

display:block Remember we said that <input> is not a block element, it is an inline element. Here we wanted to center the button using "margin:0px auto", but this doesn’t work on inline elements. That's why we set its display property to "block", and now our submit button behaves as a block element, and we can apply "margin:0px auto", to center it.

Finally, here’s how our final output looks like:

Well done mate, you did it.

A quick recap of the concepts we learned

  • How to create an element that covers entire screen using width:100% and height:100%
  • How to make background image fit the size of the element without distorting it
  • Margin and Padding
  • Block level elements and Inline elements
  • How to centre things horizontally using “margin: 0px auto”
  • How to make an element “flex” using “display:flex” so that we can vertically centre its children using “margin: auto”.
  • How to make a Form in HTML
  • How to use fonts from Google fonts
  • How to get user input using input textbox, radio button, checkbox, dropdown (select), and submit button.

HTML Tags we covered:

  • General tags: div, br
  • Form tags: form, input, label, select, options

CSS Properties we covered:

  • Background properties: background-image, background-size, background-position
  • Font Properties: font-family, font-size, letter-spacing, color
  • Display types: flex, block (“display:flex” and “display:block”)
  • Positioning: margin, padding
  • Size: max-width, min-height

Subscribe at supersarkar.com for more fun Programming tutorials.

Thanks for reading! :)

--

--

Kunal
Frontend Shortcut

Demystifying life and thinking with first principles. Twitter: twitter.com/KunalBSarkar