Demo
This is not responsive so I suggest you to view Demo in full new window. Click on the top right most button to view in full window.
Video Tutorial
If you find this tutorial helpful please subscribe to my youtube channel. Thanks
Let's Code this
To code this we will use HTML, CSS, and JS (to create animation). So first make files named index.html
, style.css
, app.js
and write basic structure of HTML also add css, js file to index.html
.
When you are done with this. Inside <body>
tag make a <div>
with class .form-container
this will be our parent of both forms. Now inside of that <div>
make another <div>
with class .bg-container
and this will contain 3 span which we use as a fake background for our Forms. Now inside of .bg-container
make a <span>
and give it class .bg
plus give it .top
class also. Now make two more copies of this span but change their .top
class to .middle
and .bottom
respectively.
This should look like this
<div class="form-container">
<div class="bg-container">
<span class="bg top"></span>
<span class="bg middle"></span>
<span class="bg bottom"></span>
</div>
</div>
Now style this.Add this CSS.
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
*:focus{
outline: none;
}
body{
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-image: url(bg.jpg);
background-size: cover;
perspective: 1000px;
}
.form-container{
width: 320px;
height: 500px;
position: relative;
transition: 1s;
display: flex;
justify-content: center;
align-items: center;
}
.bg-container{
width: 100%;
height: 100%;
position: absolute;
perspective: 1000px;
transition: 1s;
top: 0;
}
.bg{
position: absolute;
left: 0;
background: #fff;
width: 100%;
height: calc(100% / 3);
transition: 1s;
}
.bg.top{
top: 0;
transform-origin: bottom;
}
.bg.middle{
top: calc(100% / 3);
}
.bg.bottom{
bottom: 0;
transform-origin: top;
}
This css is very easy to understand as we what we did is we set a background image to body and aligning our form in center with flex box. And we also style out span and gave them different top, bottom values. So that they look like background of our forms.
Now create form. Inside .form-container
element make a <form>
and give class .form
(yeah! very unique class name).Now inside of form make an h1
element and give class .form-title
and type in login form
and then add labels and inputs for our email and password. After that add <a>
(anchor tag) with class .btn
and a <p>
tag with class .link
. And copy this structure to make register form. Do some changes and your structure should look like this.
<form class="form active" id="login-form">
<h1 class="form-title">login</h1>
<label for="email">e-mail</label>
<input type="email" id="email" autocomplete="off">
<label for="pass">password</label>
<input type="password" id="pass">
<a href="#" type="submit" class="btn">log in</a>
<p href="#" class="link">new here ? sign up now</p>
</form>
<form class="form" id="register-form">
<h1 class="form-title">sign up</h1>
<label for="name">name</label>
<input type="text" id="name" autocomplete="off">
<label for="email">e-mail</label>
<input type="email" id="email" autocomplete="off">
<label for="pass">password</label>
<input type="password" id="pass">
<a href="#" type="submit" class="btn">sign up</a>
<p href="#" class="link">already have an account ?</p>
</form>
Now Style this also.
.form{
width: 90%;
height: 100%;
position: absolute;
padding: 40px 20px;
font-family: roboto, sans-serif;
transition: 1s;
opacity: 0;
pointer-events: none;
}
.form.active{
opacity: 1;
pointer-events: all;
}
.form-title{
font-size: 40px;
text-transform: capitalize;
text-align: center;
margin-bottom: 50px;
font-weight: 400;
}
label{
display: block;
text-transform: capitalize;
}
input{
border: none;
width: 100%;
margin-bottom: 30px;
height: 30px;
background: none;
border-bottom: 1px solid #000;
}
.btn{
text-decoration: none;
color: #fff;
background: #000;
text-align: center;
width: 100px;
display: block;
margin: 20px auto;
padding: 10px 0;
text-transform: capitalize;
border-radius: 50px;
}
.link{
color: #000;
text-transform: capitalize;
display: block;
margin: auto;
width: fit-content;
text-decoration: underline;
cursor: pointer;
}
#register-form{
padding: 30px 20px;
}
#register-form .form-title{
margin-bottom: 30px;
}
By now we are done with our styling and we gave basic styling not that good. But it's time to create that effect. Open app.js
and write this.
const topSpan = document.querySelector('.bg.top');
const bottomSpan = document.querySelector('.bg.bottom');
const bgContainer = document.querySelector('.bg-container');
// select forms
const loginForm = document.querySelector('#login-form');
const registerForm = document.querySelector('#register-form');
// select links
const registerUrl = document.querySelector('#login-form .link');
const loginUrl = document.querySelector('#register-form .link');
let rotateVal = 1;
const toggleFormAnim = () => {
topSpan.style.transform = `rotateX(-180deg)`;
setTimeout(() => {
bottomSpan.style.transform = `rotateX(180deg)`;
setTimeout(() => {
bgContainer.style.transform = `rotateY(${rotateVal * 180}deg)`;
setTimeout(() => {
bottomSpan.style.transform = `rotateX(0)`;
setTimeout(() => {
topSpan.style.transform = `rotateX(0)`;
rotateVal++;
}, 1000);
}, 1000);
}, 1000);
}, 1000);
}
registerUrl.addEventListener('click', () => {
loginForm.classList.remove('active');
setTimeout(() => {
toggleFormAnim();
setTimeout(() => {
registerForm.classList.add('active');
}, 5000);
}, 500);
})
loginUrl.addEventListener('click', () => {
registerForm.classList.remove('active');
setTimeout(() => {
toggleFormAnim();
setTimeout(() => {
loginForm.classList.add('active');
}, 5000);
}, 500);
})
Now let's understand what we did in JS. First we select our two spans one topSpan
and second bottomSpan
. after that we select our two forms first loginForm
and second registerForm
after that we select our two links first registerUrl
and second loginUrl
.Then we create a variable called rotateVal
this variable is very important to keep track of our form rotation.
Then we declared a function toggleFormAnim
which is setting up our topSpan
rotateX to -180deg
and after 1s setting up bottomSpan
rotateX to 180deg
and then wait for a second to execute other command. After that we added click event to those links where we are remove .active
class from undesired form and adding .active
class to the desire one. Plus we also calling out toggleFormAnim
function.
So I hope you understand each and everything. If I made any mistake or you don't understand anything feel free to ask in comment.
Thanks for visiting : )
Top comments (2)
I can appreciate the effort that went into this, but why would you implement a transition that takes several seconds - especially if people make a mistake and then have to go back?
Having both forms on the same page but one only visible through running some script smells a little to me. You will need to style for the scenario where people don't have javascript running - and if you can make it work with both forms on the page, why not just have both forms on the page?
My final concern is with sharing links - say you have a link somewhere in your FAQ that talks about the benefits of signing up. As it stands, that link can't actually link to the registration form, but will present the login form and require the user take an extra step, and be taken out of what would otherwise seem like smooth navigation. You could address that by passing through a query parameter or fragment to tell the script which form to display first, though that probably gives you other problems instead.
I understand this but I just made these thing to show the power of Css and JS of course this form is not practical but I want people to let them know how to think like this. Thanks