Using React and Styled-Components to make a simple loading animation.
Lets get this out of the way up front. I suck at designing animations. But I would love to show you my love of creating animations, that others designed, using React and Styled Components.
There is plenty of drama around CSS in JS, but I’m going to leave that out of this article and I ask you do the same.
Below is the animation we are going to be creating today, its super simple but should demonstrate our point effectively.
Getting Setup
For this example I spun up a quick create-react-app project. If you have not heard about create-react-app at this point I suggest you head over to their repo and check it out. Totally optional, but your mind will be blown!
Now lets get on to setting up styled-components, assuming you have your React app up and running.
Install Styled Components
Run npm install styled-components
in your project to install Styled Components.
Create an Animation Component
Lets create a component that we will abstract our animation too. This mean we will be able to reuse that component in the future. I created a file named LoadingDots.js
.
My component contained the following.
import React, { Component } from "react";
import styled, { keyframes } from "styled-components";class LoadingDots extends Component {
render() {
}
}export default LoadingDots
The Actual Code
Now that we are setup and ready lets go ahead and start creating our animation. Notice how we are already loading in styled
and keyframes
into our file. These are the things from styled-components
we are going to need for this example.
Lets start off by laying out our styled components in our render function as we will want them to be displayed. We have not actually created these components yet, we will do that in just a minute.
import React, { Component } from "react";
import styled, { keyframes } from "styled-components";class LoadingDots extends Component {
render() {
return (
<DotWrapper>
<Dot delay="0s" />
<Dot delay=".1s" />
<Dot delay=".2s" />
</DotWrapper>
)
}
}export default LoadingDots
Above you can see that we are rendering a component called DotWrapper
and then 3 Dot
components inside of that. Each of the Dot
components accepts a delay
variable. This allows us to get the delayed bouncing animation.
Next lets create the animation that we will be using later. Insert the following code above the LoadingDots
class. Lets look at some code then talk more about it.
const BounceAnimation = keyframes`
0% { margin-bottom: 0; }
50% { margin-bottom: 15px }
100% { margin-bottom: 0 }
`;
The great thing about styled-components is that we are basically writing normal CSS, with some great extra features you’ll start to see below. I wont spend any time explaining what the css here does, if your confused head over and checkout the MDN page on css animations.
Next lets work backwards and create our Dot
component. Same as above, lets look at some code first then we can talk more about it. Place this code below the BounceAnimation
and above the LoadingDots
class.
const Dot = styled.div`
background-color: black;
border-radius: 50%;
width: 10px;
height: 10px;
margin: 0 5px; /* Animation */
animation: ${BounceAnimation} 0.5s linear infinite;
animation-delay: ${props => props.delay};
`;
The first thing to notice from the code above is the styled.div
line. Styled components works by declaring what type of Html element you would like to render, in our case its a div
. After that we write our css inside a template literal which allows us to pass in variables and functions. If you have not heard of template literals please checkout my article on them.
The first several lines of css are fairly cookie cutter, we are making a black circle and giving it a little bit of spacing. The next few lines starting at /* Animation */
are where things really start to get interesting.
The first thing to notice is that where we would normally state our animation name we instead reference the animation we created above ${BounceAnimation}
. This is how our styled component knows which animation to use.
The next thing to notice is that we use animation-delay
to get our dots to have the offset bouncing affect. If we pass in a function inside of a template literal string Styled Components knows to pass back props as an arguement. These are all of the things that you passed into the styled component, in our case that is the prop delay
. So by writing ${props => props.delay}
we are passing in our delay value to the styled component.
There is just one more step left. We need to create DotWrapper
that takes all of our dots and puts them on the same line. Right now they will be all stacked on top of each other. Place DotWrapper
above the Dots
component and below the BounceAnimation
component.
const DotWrapper = styled.div`
display: flex;
align-items: flex-end;
`;
The CSS here fairly simple if you know a bit about flexbox. If you want to take your flexbox knowledge to the next level check out the great comprehensive guide by on flex CSS Tricks.
Put It All Together
Now if we put it all together it looks something like this.
import React, { Component } from "react";
import styled, { keyframes } from "styled-components";const BounceAnimation = keyframes`
0% { margin-bottom: 0; }
50% { margin-bottom: 15px }
100% { margin-bottom: 0 }
`;const DotWrapper = styled.div`
display: flex;
align-items: flex-end;
`;const Dot = styled.div`
background-color: black;
border-radius: 50%;
width: 10px;
height: 10px;
margin: 0 5px; /* Animation */
animation: ${BounceAnimation} 0.5s linear infinite;
animation-delay: ${props => props.delay};
`;class LoadingDots extends Component {
render() {
return (
<DotWrapper>
<Dot delay="0s" />
<Dot delay=".1s" />
<Dot delay=".2s" />
</DotWrapper>
)
}
}export default LoadingDots
Fairly simple right! The concepts here can easily be carried onto much more complex animations. Hopefully this has taught you a bit about Styled Components and how they can be easily used to write CSS and create animations.
If you want to learn more about Styled Components checkout their documentation. Its some of the best documentation I’ve seen in a long time, its a joy to study.
Thanks!
Thanks for reading! If your interested in occasional articles about Javascript and Frontend web development feel free to drop a follow here on Medium!
Any questions or concerns? Drop them in the comment section below and I’ll happily answer them as quickly as possible!