WALKTHROUGH: Creating a Responsive ReactJS Website

Danny Calise
5 min readJan 11, 2021

This article will cover the following topics with steps:

1. Css animations

2. Static background image

3. A Scrolling Div

4. Static Silhouette Footer

5. Hidden Divs

6. React-datepicker

7. EmailJS

I was commissioned to make a website for a moving (and more!) company and was given a few parameters before I got started.

The customer wanted the aesthetic to be similar to this album cover:

with a silhouette of Philadelphia overlaying the bottom of the screen.

With those limited parameters, I was able to get creative with everything else.

CSS Animations

In order to create a CSS animation, in your CSS file, you should establish an animation like so (this one is called ‘bobble’ which is a random name I gave it):

@keyframes bobble {
0% {
transform: translate3d(50%, 20px, 0px);
animation-timing-function: ease-in;
}
50% {
transform: translate3d(50px, 20px, 0px);
animation-timing-function: ease-out;
}
100% {
transform: translate3d(20px, 20px, 0px);
}
}

At 0% (the beginning of the animation), whichever div you assign “animation: bobble” will be transformed using the attribute “transform”.

Since the value of transform is “translate3d(50%, 20px, 0px)”, this means the div will move 50% to the right on the x-axis, the div will move 20px down the y-axis, and 0px on the z-axis.

The “animation-timing-function” attribute with a value of ease-in means that the div will, well, ease into its new spot.

At the 50% and 100% marks, the div will shift as noted.

**But this alone isn’t enough to create an animation!**

You also have to assign this animation to whatever div you choose. In my case, I used “.title-text”:

.title-text {
animation: bobble 3s;
}

This tells the div to complete the animation called “bobble” in 3 seconds…or else!

Static Background Image

I struggled at first to place a background image behind this div, but I figured out that you don’t need to use the css “background-image” attribute in order to accomplish this.

Instead, you can use the “position” and “opacity” attributes in order to have the effect of a background image.

.arch-image {
position: absolute;
width: 100vw;
height: 55vh;
opacity: 0.2;
}

The next step is to place the “.arch-image” div at the top of the div where you want it to be the background image:

<div className="scroll-rows">
<ArchImage />
<div className="button-row">
...

Since I put my image in a component (“<ArchImage />” above), here is the ArchImage component:

import React from 'react';
import img from '../images/arch.jpg';


function ArchImage() {
return <img src={img} className="arch-image" alt="Arch" />;
}

export default ArchImage;

A Scrolling Div

In order to achieve a scrolling effect, I used the “overflow-x” attribute in my CSS file, to ensure that the excess content goes vertically below the top content.

And in order to get the actual physical scrollbar on the right side, I used “:-webkit-scrollbar” to specify what I wanted the scrollbar to look like.

.scroll-rows {
border: 4px solid black;
height: 56.5vh;
min-width: 200px;
width: 100vw;
display: flex;
justify-content: center;
overflow-x: hidden;
}
.scroll-rows::-webkit-scrollbar {
width: 1em;
}

.scroll-rows::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
}

.scroll-rows::-webkit-scrollbar-thumb {
background-color: darkgrey;
outline: 1px solid slategrey;
}

Static Silhouette Footer

The customer specified that he wanted a silhouette of the city of Philadelphia to start at the bottom of the page and overlay the main page, up to a quarter of the way up the screen.

When styling the “.city-image”, I used “position: absolute” to ensure that the image will be fixed to the bottom of the page.

.city-image {
position: absolute;
width: 100%;
height: 15em;
}

Additionally, to make sure that the image appears at the bottom of the page, I put the <CityImage /> at the bottom of the container:

...  
<div className="city-row row">
<CityImage />
</div>
</Container>

Hidden Divs

Since I want the form to change based on the specifications that the user chooses, I want some divs to be hidden unless certain checkboxes are selected.

For example, when the “Moving” checkbox is selected, I want the calendar to appear below it.

To do this, when the “Moving” checkbox is checked, the state of isMoving changes from false to true. Meanwhile, I assign the hidden calendar div the className placeholder “movingHidden”, which becomes ‘calendar row’ if the “Moving” checkbox is checked or remains ‘hidden’ if the “Moving” checkbox is unchecked:

const movingHidden = this.state.isMoving ? 'calendar row' : 'hidden';

React-datepicker

Just when I thought I had the React-datepicker all figured out and functioning, I noticed that the date being displayed wasn’t changing when I selected a date. To remedy this, I established this.state.controlledDate:

this.state = {
controlledDate: new Date()
}

And assigned “this.state.controlledDate” to the “selected” attribute of the DatePicker:

<div className={movingHidden}>
<h2>When are you looking to move?</h2>
<DatePicker
className="date-picker"
selected={this.state.controlledDate}
onChange={this.handleDateChange.bind(this)} />
</div>

Then, using Moment.js, I assigned “realDate” the value of the date the user selected:

handleDateChange = (date) => {
var dateFormatted = moment(date).format("MM-DD-YYYY");

this.setState({
controlledDate: date,
realDate: dateFormatted
});
}

EmailJS

The customer wanted a summary of the form to be sent to his email when the form was submitted. In order to do this, I used EmailJS.

In the handleSubmit function, I added the EmailJS code like so:

handleFormSubmit = event => {
event.preventDefault();
var templateParams = {
name: 'Daniel',
notes: 'Check this out!'
};
emailjs.send('<YOUR SERVICE ID>','<YOUR TEMPLATE ID>', templateParams)
.then(function (response) {
console.log('SUCCESS!', response.status, response.text);
}, function (err) {
console.log('FAILED...', err);
});

}

When the user presses the “Submit” button, an email is sent to me based on the Service ID I put in the emailjs parameters. It also uses the template I established on emailjs.com, which conveniently puts all of the information into an easily readable table.

Conclusion

All in all, I was able to use several technologies in order to make this (somewhat) simple website function. Let me know if you have any questions in the comments below!

-Danny Calise

--

--

Danny Calise

Freelance coder, 10 year educator, music maker, and avid reader