loading...
Cover image for Build This Cool Sign-In Form with React and CSS

Build This Cool Sign-In Form with React and CSS

cooljasonmelton profile image Jason Melton ・4 min read

Background

After reading Vasudha Mamtani’s blog about sign-up pages, I realized I had been taking them for granted.

Having a solid sign-up page affects whether or not someone uses your website. Would you enter your email into a wonky looking sign-up form?

After looking through the examples in Mamtani’s blog, I decided to try my hand at making a better sign-in page. I came up with this:

Alt Text

The plan here is for a user to only see the abstract image when switching between signing in and creating an account.

I’m trying to imply that there’s a complicated inner working to this website. We are capable of great and complicated things. Trust us!

Tutorial

In the following, I’ll explain how to code one of these sign-up pages using React and CSS.

Link to GitHub

Table of Contents

  • Preliminary Junk
  • Container Layout
  • Banner and Form Transitions
  • Conditionally Render Sign-In / Sign-Up
  • Conclusion

Preliminary Junk

First, as has become ritual for these blogs, I installed a create-react-app, deleted default stuff, and set up a file structure and components.

Alt Text

File Structure

As you can see, there are three main components. Container.js is my outermost element. Inside it, there are two divs for the form side and the banner side.

Then, there are two form components for whether you are signing in or creating a new account, SignIn.js and SignUp.js respectively. These are conditionally rendered on the form side of Container.js.

I added a CSS class called cfb (center flexbox). To reduce repetition, whenever I need contents of a div centered, I throw on a cfb. As needed, I add other flex-related properties, like flex-direction, to the specific element.

.cfb{
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
}

Container Layout

Container div

I style the main div in Container.js like this:

Alt Text

.Container{
    position: relative; 

    width: 50%;
    height: 60%;

    box-shadow: 1px 2px 2px #592941;
    border: 0.1em solid #592941;
    border-radius: 0.5em;

    background-image: url('./shapes.jpg'); 
}

Form Side and Banner Side

Next, I create the divs for the banner and form side of Container.js.

Alt Text

.banner-side{
    position: absolute;
    z-index: 2;
    right: 65%;

    border: 0.1em solid #592941;
    border-radius: 0.5em;

    width: 35%;
    height: 100%;

    flex-direction: column;

    background-color: #035E7B;
    opacity: 1;

    color: #EEFCF8;
    text-align: center;

    transition: 2s;
}
.form-side{
    position: absolute;
    z-index: 1;
    right: 0;

    border: 0.1em solid #592941;
    border-radius: 0.5em;

    width: 65%;
    height: 100%;

    background-color: #EEFCF8;
    opacity: 1;

    font-weight: bold;
    color: #035E7B;

    transition: 2s;
}

Banner and Form Transitions

Positioning

So the transitions work properly, I set up CSS properties for position, right, z-index, and transition.

To make the divs free to move, they must be styled with a position: absolute;. Then, they will align themselves within the nearest positioned parent element. This means I also must style the main div in Container.js to have a position: relative;.

I’ve styled the size of the divs with percentages. I use these same sizes to set how far right they should be.

First, the form-side is set at right: 0;. It will sit flush on the right side of the container.

Because the form-side is 65% of the parent element, I set the banner-side to be right: 65%;. It starts where the form-side ends.

To get banner-side to hover over form-side, I give banner-side a z-index: 2; and the form-side a z-index: 1;.

Finally, I give them each a transition: 2s;. When I change their right properties, they will move fluidly from their starting place to the next for the duration of two seconds.

Triggering Transitions by Updating Classes

The positioning of banner-side and form-side will be based on whether I am rendering a sign-in or sign-up form.

I set up two new classes for where the banner-side and form-side will be when they are reversed.

.send-right{
    right: 0;
}

.send-left{
    right: 35%;
}

I apply these new classes with functions.

const Container = () => {
  const [welcome, setWelcome] = useState(false);

  const setBannerClass = () => {
    const classArr = ["banner-side cfb"]
    if (welcome) classArr.push('send-right')
    return classArr.join(' ')
  };

  const setFormClass = () => {
    const classArr = ["form-side cfb"] 
    if (welcome) classArr.push('send-left')
    return classArr.join(' ')
  };
  return (
    <div className="Container cfb">

      <div className={setBannerClass()}> 
      </div>

      <div className={setFormClass()}> 
      </div>

    </div>
  );
}

My useState hook contains a boolean called welcome. When welcome is updated, the component will re-render and the classes will be updated based based on that boolean.

Finally, I put up a button in the banner to trigger setWelcome() in the useState hook.

        <button onClick={()=> setWelcome(!welcome)}>
          ~Change~
        </button>

Conditionally Render Sign-In / Sign-Up

The final touch is to change the forms and and banner text based on whether our user intends to sign-in or create a new account. To do this, I used the same welcome from my useState hook.

  return (
    <div className="Container cfb">

      <div className={setBannerClass()}> 

        {welcome ? 
          <h2>Hello, New Friend!</h2>
            : <h2>Welcome Back</h2>}

        <button onClick={()=> setWelcome(!welcome)}>
          {welcome ?
            "Sign In"
              : "Create Account"}
        </button>

      </div>

      <div className={setFormClass()}> 
          {welcome ? 
            <SignUp /> 
              : <SignIn/>
          }

      </div>
    </div>
  );

Because this is a dummy project, I didn’t do anything specific with the forms themselves. If you’d like, you can check them out on GitHub.

Conclusion

This was a fun one to figure out. The newest concept for me was a deeper understanding of position and z-index.

I've used this properties before, but I had been flying by the seat of my pants. I’m happy for my newfound confidence with them.

Taking this project further, I would also animate the rendering of the text and forms themselves. A smooth transition would improve the page.

As always, thanks for reading. I hope this helped you somehow.

Discussion

pic
Editor guide