DEV Community

Cover image for Have you ever seen foldable login form ?
Modern Web
Modern Web

Posted on

Have you ever seen foldable login form ?

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>
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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);
})
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
moopet profile image
Ben Sinclair

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.

Collapse
 
themodernweb profile image
Modern Web

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