In part 1 of this tutorial, we will be building a clone of the Windows Login page using HTML and SCSS. By the end of this simple tutorial, you’ll be able to understand how to use mixins to write reusable code and how to apply multiple animations to certain components in this project. As always, this tutorial is beginner friendly. Enjoy! :)
Sketch
First things first, we need to have an idea of the layout of the login page. We already know what the Windows login page looks like. However, by sketching the basic outline of the main components that the Login page is made up of, it will help us with the structure of our HTML code. This sketch of the Windows Login page will serve as our blueprint. a map of sorts.
The main components of the Windows Login page are:
- User profile(display) image
- Account user name
- Password input box
- Submit button
HTML
With the components that make up the Windows Login page in mind, we can now start to write our HTML code.
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<title>Windows Login Page UI </title>
</head>
<body>
<!--Login Page -->
<div id="login-page" class="login-page">
<div id="login-page-inner">
<!-- User Icon -->
<div id="user-icon-container">
<i class="fa fa-user-o fa-5x"></i>
</div>
<!-- Username -->
<div id="username-container">
<h2>Muna</h2>
</div>
<!-- Password box -->
<div id="input-container">
<input type="password" id="password" placeholder="Enter password">
<button id="submit"><i class="fa fa-arrow-right"></i></button>
</div>
</div>
</div>
</body>
</html>
We’ll start off with a basic HTML skeleton. Here I’ve used the standard HTML skeleton that is provided by Codepen. You can access this basic HTML skeleton by typing the word doc in the HTML section in Codepen’s coding playground and then clicking the tab key on your keyboard.
We’ll be using a couple of icons from an icon library called FontAwesome. To enable us to make use of this library, we need FontAwesome’s CDN(Content Delivery Network)link. After retrieving FontAwesome’s CDN link, we will place it in between the head tag in our HTML using a link tag, as shown above. For future use, you can find FontAwesome’s CDN link easily by typing ‘Fontawesome cdn link’ into Google, or any search engine of your choice or click here.
In the body section, we’ll type in the main code that will make up our Windows Login page. We’ll start with the main container that will hold the contents of the login page in place. We’ll give the main container an id of login-page-container. Next, we’ll add another div that will enable us to move the components of the login page around the login-page div container. This will help us with positioning the components better. We’ll give this container an id of login-page-inner.
Following this, we’ll add our main components that will make up the login page; the user display image, the account username, the password input box and the submit button.
Let’s begin with our first component. the user display image. We’ll be using an icon from FontAwesome’s icon library to represent the user . To hold this icon, we’ll add a div container with an id of user-image-container. Inside the user-image-container div will be the user icon that will represent the user profile image. Using the i tag, we’ll add the classes fa, fa-user-o and fa-5x. The first class represents the prefix for FontAwesome icons and without it, you won’t be able to make use of the icon library so do not forget to include this. The second class name, fa-user-o, of the i tag represents the name of the icon that we are using from FontAwesome’s library. The last class name of our i tag, fa-5x, represents the size of the icon and is used to increase the icon size.
Our next component after the user-icon-container is the account user name. We’ll use a div, with an id of username-container, to act as a container for the user name. Inside the username-container div, we’ll use a heading tag, a h2 tag in this case, for the username.
The last two components are the password input box and the submit button. We’ll use a div container to hold these two components. We’ll give this div container an id name of input-container. Inside the input-container div, we’ll have an input tag that will represent the password input box. We’ll change the input tag’s type attribute to password because this will be what the input tag will be representing. We’ll also give the input tag an id of password and a placeholder of ‘Enter Password’. This placeholder attribute is used to give a short description of the expected value of this input field, in this case a password. The last component to add in our input-container div is the submit button. We’ll add a button tag and give it an id of submit.In between the button tag we’ll insert another icon, this time a right-facing arrow icon, using the i tag by giving it the class names fa and fa-arrow-right.
SCSS
On to the styling!
Helpful tip alert!
Before we start with the styling, I want to let you know about a very helpful tip I learned about from a developer on Twitter (who’s Twitter handle I, unfortunately, cannot remember). For layout debugging and the ability to have visual representation of the layout to simplify editing, use the following at the top of your stylesheet;
* {
outline: 1px solid red;
}
What this does is add a red outline around each and every element from our HTML code.The great thing about this is that unlike debugging via the use of the border property, using outline doesn’t add any extra pixels so it won’t affect our layout.As you continue through the tutorial, you’ll see how this debugging solution works.
Now let’s get on to some actual styling!
Login-page-container
body {
margin: 0;
padding: 0;
}
#login-page-container {
width: 100%;
height: 600px;
background-image: url("http://res.cloudinary.com/mmdirir94/image/upload/v1519167949/architecture-3121009_960_720_lix21u.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
font-size: 16px;
color: white;
}
We’ll start by getting rid of the default margin and padding that the body tag has by setting both the margin and padding to a value of 0.
On to styling the main container; login-page-container.
We’ll give the login-page-container a width of 100%, which will make it span across the full width of the content area and responsive so that the background-size changes depending on the browser size. We’ll also give the login-page-container div a height of 600 pixels.
We’ll then use the background-image-url property to insert a background to the login-page-container div. We’ll center the background image by using the background-position property and giving it a value of center. We’ll make sure that the background image isn’t repeated across the login-page-container by giving it a value of no-repeat. Next, we’ll use the background-size property to specify the size of the background image. By giving the background-size property a value of cover, it will resize our background-image so that it fills the entire login-page-container and will do so even if it this results in stretching the image or cutting parts of it off.
Lastly, we’ll give the color property a value of white. This will make the default color of any text in the login-page-container or any of its child elements to be white. I have chosen the default text-color to be white because that is the color that works best against the background image I have used and is also the color that allows the text to be the most legible(i.e. easy to read) against the background image.
Login-page-inner
#login-page-container {
width: 100%;
height: 600px;
background-image: url("http://res.cloudinary.com/mmdirir94/image/upload/v1519167949/architecture-3121009_960_720_lix21u.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
font-size: 16px;
color: white;
#login-page-inner {
width: 400px;
margin: 0 auto;
@include vertical-centering;
}
}
Moving on to the login-page-inner div container, we start by nesting it within the login-page-container div. In case you are not familiar with nesting, it is one of the many features of SCSS. It allows us to create a visual hierarchy that is the similar to the one in our HTML code. Not only does it make our SCSS code more organised and readable, but once the SCSS code is compiled to CSS(this is done automatically in Codepen), it also makes our CSS more organised and readable too.
We’ll give the login-page-inner div a width of 400 pixels and center it horizontally by using the margin property and setting its value to margin: 0 auto.
To vertically center the login-page-inner div within the login-page-container div, there are a few ways. In this case, rather than using flexbox, we’ll vertically center the login-page-inner div using the position property, top property and transform property. Together, these 3 properties combined allow you to vertically center the login-page-inner div within its parent container, login-page-container. In case we need to vertically center later on in our code, we’ll use a mixin and name it vertical-centering.
@mixin vertical-centering {
position: relative;
top: 50%;
transform: translateY(-50%);
}
I have placed the vertical-centering mixin at the top of our SCSS stylesheet and to apply it, I have used @include followed by the name of the mixin.
Below we can see what our login page looks like so far.
Login-page-inner → Animation
We’ll apply a simple animation where the login-page-inner div, including all of the elements which are nested within it, will descend from above and fade in from 0 to full opacity.
//Animations
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
Let’s start with the fading in animation. To create an animation, we use @keyframes followed by the animation name, which is fadeIn. Then it’s quite simple — we want the login-page-inner div, including all its content, to change from an opacity of 0 to an opacity of 1 (i.e. full opacity).
@keyframes descend {
from {
top: 45%;
}
to {
top: 50%;
}
}
Next is the animation which will make the login-page-inner div, as well as the elements within it, descend. We want the login-page-inner-div to move downwards to where the login-page-inner div is vertically centered within the login-page-container. We’ll use @keyframes followed by the animation name, which in this case is descend. Next, we’ll make it so that the starting point of the login-inner-container div is 5% above the center of the parent container(#login-page-container) and the ending point is the center of the parent container(#login-page-container) .
All that is left is to apply both animations to the login-page-inner div using the animation property.
...
#login-page-inner {
...
...
animation: fadeIn 1s ease-in-out, descend 0.5s ease-in-out;
}
The first animation is fadeIn — it will last 1 second and have a transition-timing function of ease-in-out which means that the animation will have an equally slow start and end. Separated by a comma, the next animation is descend. The descend animation will last 0.5 seconds and similar to the fadeIn animation, will also have a transition-timing function of ease-in-out.
The end result will look like this:
User-image-container
#login-page-container {
width: 100%;
height: 600px;
background-image: url("http://res.cloudinary.com/mmdirir94/image/upload/v1519167949/architecture-3121009_960_720_lix21u.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
font-size: 16px;
color: white;
#login-page-inner {
width: 400px;
position: relative;
@include vertical-centering;
margin: 0 auto;
animation: fadeIn 1s ease-in-out, descend 0.5s ease-in-out;
#user-icon-container,
#username-container,
#input-container {
text-align: center;
}
#user-image-container {
margin: 0 auto;
width: 140px;
height: 140px;
font-size: 110%;
border-radius: 100%;
background-color: rgba(255, 255, 255, 0.5);
.fa-user-o {
line-height: 140px;
}
}
}
}
From what we’ve done so far, we can see that the content within the login-page-inner div is aligned to the left. To fix this, we will change the text-align value to center for all 3 of the main components that make up our login page.
Next we’ll style the first main component of the login page; the user profile image. Let’s start by styling the user-image-container div — this will act as the background for the user icon that is nested within the user-image-container div.
To horizontally center the user-image-container within its parent container, #login-page-inner, we’ll give the user-image-container div a margin of ‘0 auto’. We’ll give the user-image-container a equal width and height of 140 pixels.
We’ll apply a font-size of 110% which means that the font-size of any text (or icons) within the user-image-container div will be 110% of the size of our default font-size(16px) which we set earlier in the main parent container, #login-page-container.
The user-image-container div that will serve as our background will be circular so to do that, we’ll make the border-radius value to be 100%.
Lastly. the background-color of the user-image-container div will be white and slightly transparent. To achieve this, we use RGBA colors as it allows us not only to define the color values that are defined by RGB colors but also allows us to define the opacity of the color.
User-image-container → user icon
Moving on to the user-icon, which is nested in the user-image-container div, we’ll apply a line-height of 140 pixels. This will vertically center the user icon within the user-image-container div.
Username-container
#login-page-container {
width: 100%;
height: 600px;
background-image: url("http://res.cloudinary.com/mmdirir94/image/upload/v1519167949/architecture-3121009_960_720_lix21u.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
font-size: 16px;
color: white;
#login-page-inner {
width: 400px;
position: relative;
@include vertical-centering;
margin: 0 auto;
#user-image-container,
#username-container,
#input-container {
text-align: center;
}
#user-image-container {
margin: 0 auto;
width: 140px;
height: 140px;
font-size: 110%;
border-radius: 100%;
background-color: rgba(255, 255, 255, 0.5);
.fa-user-o {
line-height: 140px;
}
}
#username-container {
margin-bottom: 40px;
margin-top: 20px;
font-family: "Roboto";
font-size: 105%;
}
}
}
The next main component of the login page is the account user name. We’ll start with the username-container div.
We’ll apply a margin bottom of 40 pixels so that there is some space between the username-container div and the input-container div (which contains the password input box and submit button). We’ll also apply a margin-top of 20 pixels which will create some space between the username-container and the user-image-container div, which is above the username-container.
We will then make the value of the font-family to be Roboto. In order to use Roboto as the font-family, we will either need to add this font using @import or add the font by embedding the font in between the
tag in our HTML. Here, I’ve opted to use @import method — luckily, we can do this easily using the Assets library that is on Codepen already. See the GIF below to see how this is done.The next main component of the login page is the account user name. We’ll start with the username-container div.
We’ll apply a margin bottom of 40 pixels so that there is some space between the username-container div and the input-container div (which contains the password input box and submit button). We’ll also apply a margin-top of 20 pixels which will create some space between the username-container and the user-image-container div, which is above the username-container.
We will then make the value of the font-family to be Roboto. In order to use Roboto as the font-family, we will either need to add this font using @import or add the font by embedding the font in between the head tag in our HTML. Here, I’ve opted to use @import method — luckily, we can do this easily using the Assets library that is on Codepen already. See the GIF below to see how this is done.
We’ll make our font-size equal to 105% which means that the font-size will be 105% of the size of our default font-size (i.e 16px) which we set earlier in the main parent container, #login-page-container.
Here’s what we have so far:
Input-container
#login-page-container {
width: 100%;
height: 600px;
background-image: url("http://res.cloudinary.com/mmdirir94/image/upload/v1519167949/architecture-3121009_960_720_lix21u.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
font-size: 16px;
color: white;
#login-page-inner {
width: 400px;
position: relative;
@include vertical-centering;
margin: 0 auto;
animation: fadeIn 1s ease-in-out, descend 0.5s ease-in-out;
#user-image-container,
#username-container,
#input-container {
text-align: center;
}
#user-image-container {
margin: 0 auto;
width: 140px;
height: 140px;
font-size: 110%;
border-radius: 100%;
background-color: rgba(255, 255, 255, 0.5);
.fa-user-o {
line-height: 140px;
}
}
#username-container {
margin-bottom: 40px;
margin-top: 20px;
font-family: "Roboto";
font-size: 105%;
}
#input-container {
height: 50px;
#password {
margin: 0 auto;
height: 25px;
width: 300px;
padding-left: 5px;
}
#submit {
height: 31px;
padding: 0 10px;
position: relative;
right: 5px;
background-color: #bdbdbd;
border: none;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
cursor: pointer;
.fa-arrow-right {
line-height: 28px;
color: white;
}
&:hover {
background-color: #9e9e9e;
}
}
}
}
}
Finally, all we have left to style is the input container which contains our password input box and submit button.
Let’s start by giving our input-container div a height of 50 pixels.
Input-container →password input box
Moving on to the password input box (#password), we’ll begin by centering it horizontally within the input-container with margin: 0 auto. We’ll give it a height of 25 pixels and a width of 300 pixels. The placeholder value in #password is too far from the left border of #password so we’ll apply a padding-left of 5 pixels.
Input-container → submit button
Last, but not least, is our submit button.
From our HTML code, we can see that nested within the button tag is an i tag with a class name of ‘fa fa-arrow-right’ which represents our arrow icon. The button element will act as the container for our arrow icon. We’ll give our submit button a height of 31 pixels and a padding-left and padding-right of 10 pixels. This adds equal padding on either side of the arrow icon, which is horizontally centered in our button tag that has an id of #submit.
The submit button is a little too close to the password input box so we’ll first apply relative positioning using the position property and then position the submit button(i.e. #submit) 5 pixels to the right of the password input box (i.e. #password) using the right property.
Next, we’ll give the submit button a background-color of #bdbdbd and remove its border by giving the border property a value of none. To give a slight curve to the top-right and bottom-right of the submit button, we’ll give it a border-top-right-radius and border-bottom-right-radius of 2 pixels.
To indicate that the submit button is indeed a button, we’ll give our cursor property a value of pointer. In addition to this, we’ll change the colour of the button when you hover over it from #bdbdbd to #9e9e9e.
Making sure to remove the red outline we applied in the beginning of our stylesheet, our Windows login page is almost done.
We have come to the end of part one of the tutorial. In part two, we’ll cover how to make the Windows login page responsive using media queries and mixins.
For easy access, I have gathered the pens in this tutorial and put them in a collection on Codepen. You can check it out here.
Hey guys! It's been a while since I've posted on here so thought I'd eaaaase my way back in to posting with this tutorial 😄.
I hope you enjoyed part 1 of this tutorial! The second part of this tutorial will be up next week! Till then! ✌️
P.S. Thank you to everyone who's followed me these last few days, I see you! This wouldn't be possible without the dev.to team and this beautiful community we're a part of so I hope you enjoy your time on this platform! ❤️
Top comments (16)
I really love developers that takes time to explain each section of their posts and offers a partial result of each step. Nice touch to include the sketch part. Thanks!
Thank you Juan! Honestly, you've made my day 😄!With tutorials, its trial and error to see what works best so it's wonderful to know that what I'm doing so far has translated well to the readers. Thank you!
Yeah, amazing Muna.
Thank you Ben! That means a lot! 😊
This is so good!
I've used outlines/background colors for debugging my CSS before, but it hadn't occurred to me to apply them globally during development like that. Definitely going to use that trick next time I'm doing frontend stuff :)
Me too! Best tip I've come across so far! I'm glad you found the tutorial helpful! ☺
Hey Muna, so cool reading through your tutorial, especially with how much love for the detail you implemented and described everything :D As you seem to really a good sense for great UX in login processes: have you ever implemented passkeys in one of your projects? If yes, what's your opinion on that?
Thanks Muna! This is very useful. I'm new to web development. Your tutorial will help me create a great log-in page to add to my portfolio!☀️
Thank you Alverson, I'm glad you enjoyed the tutorial 😄! That's awesome to hear, best of luck with the portfolio!
Thanks again. I completed Part II. I'll tag your twitter handle when I share it.
Great tutorial! The Helpful tip alert rocks!
Thank you Nicolas! I'm glad you liked the tip 😁. Check out Twitter, it's like a goldmine for really good dev tips !
Hi Muna, Thank you for this wonderful step-by-step write up. I've always wanted to learn scss for a while now but school won't just let me.
Thanks once again for this brilliant one
Thank you for your kind words Jegede! I'm glad the tutorial helped you! :)
This is amazing. Took me step by step. Made CSS not so scary.
Thank you Ijeh! It's really good to hear that the tutorial helped you! Don't worry,CSS is always a little scary in the beginning but with time, you'll get the hang of it! 👍