Build This Cool Sign-In Form with React and CSS
Tags: css, react, javascript, design
Published: 2020-08-17 08:19:49

# Background

After reading Vasudha Mamtani’s [blog](https://uxdesign.cc/sign-me-up-8e9980efafb8) 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](https://github.com/cooljasonmelton/cool-sign-up):

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2m5pq3edil2r53ysr36t.gif)

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](https://github.com/cooljasonmelton/cool-sign-up)

### 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](https://dev-to-uploads.s3.amazonaws.com/i/x75t5jh4tq9etxxylvo9.png)

#### 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.

```css
.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](https://dev-to-uploads.s3.amazonaws.com/i/mkmvxeqiedslshxxm66g.png)

```css
.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](https://dev-to-uploads.s3.amazonaws.com/i/54htwmelpf72ckpcljls.png)

```css
.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;
}
```
```css
.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.

```css
.send-right{
    right: 0;
}

.send-left{
    right: 35%;
}
```

I apply these new classes with functions.

```javascript
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.

```javascript
        <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.

```javascript
  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](https://github.com/cooljasonmelton/cool-sign-up).

## 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.